Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

castTo HTMLInputElement/HTMLTextAreaElement failing #108

Open
tysonzero opened this issue May 10, 2024 · 8 comments
Open

castTo HTMLInputElement/HTMLTextAreaElement failing #108

tysonzero opened this issue May 10, 2024 · 8 comments

Comments

@tysonzero
Copy link

tysonzero commented May 10, 2024

When building with new js backend, the following code breaks:

setInputValue :: JSString -> JSString -> JSM ()
setInputValue elId val = do
    mdoc <- currentDocument
    for_ mdoc $ \doc -> do
        mel <- getElementById doc elId
        for_ mel $ \el -> do
            minp <- castTo HTMLInputElement el
            for_ minp $ \inp -> do
                setValue inp val

as does the equivalent code with HTMLTextAreaElement. The error message is:

TypeError: Failed to construct 'HTMLInputElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function.

and the underlying generated code that breaks is:

function h$ghcjszmdomzmjavascriptzm0zi9zi9zi0zm9L333ZZodsSjL72bj0Jts5nZCGHCJSziDOMziTypeszizdfIsGObjectHTMLInputElement1_e() {h$bh();
var h$$55b79042=window["HTMLInputElement"]();
var h$$75b79042=h$$55b79042;
h$r1=h$c1(h$baseZCGHCziJSziPrimziJSVal_con_e,h$$75b79042);
return h$rs();
};

Following the suggested fix with new just gives a different error:

TypeError: Illegal constructor

This is using commit 9b4b41a of this repo, on haskell.nix commit 660bbe7, with ghc-9.8.2.

@tysonzero
Copy link
Author

Ok castTo is even worse than I thought. Including it more or less anywhere in your code leads to the whole javascript file failing to evaluate due to invalid syntax:

function h$$5da10042() {var h$$cda10042=h$r1;
var h$$dda10042=h$stack[(h$sp-2)];
var h$$8da10042=h$stack[(h$sp-1)];
h$sp-=3;
var h$$eda10042=h$$cda10042.d1;
var h$$fda10042=h$isInstanceOf $1 $2(h$$8da10042,h$$eda10042);
var h$$0ea10042=h$$fda10042;
var h$$1ea10042=((x) => { return !(!x); })(h$$0ea10042);
if(h$$1ea10042) {h$p2(h$$8da10042,h$$6da10042);
return h$e(h$$dda10042);
};
return h$rs();
};

specifically this line:

var h$$fda10042=h$isInstanceOf $1 $2(h$$8da10042,h$$eda10042);

I initially manually fixed this and wasn't 100% sure of the underlying cause, but after replacing castTo with undefined the syntax error goes away, so I'm now confident it is the root cause.

@hsyl20
Copy link
Contributor

hsyl20 commented May 11, 2024

Foreign imports in ghcjs-dom-javascript haven't been all ported to the new syntax.

Especially this one in your case: https://github.com/ghcjs/ghcjs-dom/blob/d01210f68c46fe336f0fe74ad8b6dd9b5387e155/ghcjs-dom-javascript/src/GHCJS/DOM/Types.hs#L1058

@tysonzero
Copy link
Author

Oof that's what I get for trusting github search, yes that is definitely the problematic line.

@hamishmack
Copy link
Member

I think this is fixed now.

@ymeister
Copy link
Contributor

ymeister commented Aug 21, 2024

@hamishmack I'm having the same problem trying to use reflex-dom. I get the same error as in:

function h$ghcjszmdomzmjavascriptzm0zi9zi9zi0zm9L333ZZodsSjL72bj0Jts5nZCGHCJSziDOMziTypeszizdfIsGObjectHTMLInputElement1_e() {h$bh();
var h$$55b79042=window["HTMLInputElement"]();
var h$$75b79042=h$$55b79042;
h$r1=h$c1(h$baseZCGHCziJSziPrimziJSVal_con_e,h$$75b79042);
return h$rs();
};

But with window["Element"]() now. Manually removing the parenthesis at the end, making it into just window["Element"], fixes the problem, but I have no idea where these parenthesis come from to make a change.

Edit: Tested it on 9.8.2 and 9.10.1

@hsyl20
Copy link
Contributor

hsyl20 commented Aug 21, 2024

@ymeister You must have a foreign import somewhere that looks like:

foreign import javascript "window[\"HTMLInputElement\"]" whatever :: ...

It must be changed into a function:

foreign import javascript "(() => window[\"HTMLInputElement\"])" whatever :: ...

The JS backend only supports functions in foreign imports.

@hsyl20
Copy link
Contributor

hsyl20 commented Aug 21, 2024

Actually if you grep for foreign import javascript unsafe "window" in https://github.com/ghcjs/ghcjs-dom/blob/master/ghcjs-dom-javascript/src/GHCJS/DOM/Types.hs, there are 796 matches to fix.

@ymeister
Copy link
Contributor

@hsyl20 that makes sense! Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants