Open mperreir opened 3 years ago
I've found the reason for the issue. Svelte is compiling the attributes from camel-case to lower-case before passing them to Svelte NodeGUI. This is something I'd thought we'd solved once and for all with the PRs to Svelte from @halfnelson and @mrsauravsahu to support foreign namespaces. The Svelte NodeGUI preprocessor (and Svelte Native preprocessor from which it is forked) implicitly inserts <svelte:options namespace="foreign" />
to indicate that our host is foreign and so should not be treated as HTML. But it appears there are still some further cases where it is mistreated.
<window windowTitle="abc"/>
correctly preserves casing, i.e. it results in a correct call to widget.setProps({ windowTitle: "abc" }, {})
.
However, <text wordWrap={true}>abc</text>
strips casing, resulting in an incorrect call to widget.setProps({ wordwrap: true }, {})
.
Incidentally, <text wordWrap>abc</text>
also strips casing, resulting in an incorrect call to widget.setProps({ wordwrap: "" }, {})
.
I also tried <text wordWrap="abc">abc</text>
, which also strips casing, resulting in an incorrect call to widget.setProps({ wordwrap: "abc" }, {})
.
So it has nothing to do with the values being booleans or strings. I guess Svelte must be special-casing certain attributes from the HTML5 spec, as wordwrap
and readonly
.
I can't find any mentions of wordwrap
in the Svelte repo, but there are some indications that readonly
may be treated as a special case in some manner:
I'm just surprised that this is biting us when we're in a foreign namespace. Does this analysis seem plausible @halfnelson, @mrsauravsahu?
Mentioned PRs:
A horrible workaround for now if it's blocking you:
// BetterText.svelte
<script lang="ts">
import type { NSVElement, RNText } from "@nodegui/svelte-nodegui";
let ref: any;
export let wordwrap: boolean = false;
// Find some way to map out the other attributes you need.
// There is probably a clever Svelte way to extend all those of RNTextProps, but I don't know how!
$: {
if(ref){
/** With reference to the setTextProps() method in: src/dom/react-nodegui/src/components/Text/RNText.ts */
(ref as NSVElement<RNText>).nativeView.setWordWrap(wordwrap);
}
}
</script>
<text bind:this={ref}><slot></slot></text>
And use like this:
<script lang="ts">
import BetterText from BetterText.svelte
</script>
<BetterText wordwrap={true}>abc</BetterText>
Far from perfect, but at least it allows to set wordWrap
and readOnly
on components that need it :-).
Looking at the Svelte JS output of the same code in the repl (https://svelte.dev/repl/a64f21f99f3d48de992a731a76818c32?version=3.37.0) gives us a clue
c() {
window_1 = document.createElementNS("https://svelte.dev/docs#svelte_options", "window");
view2 = svg_element("view");
view0 = svg_element("view");
text0 = svg_element("text");
//snip
attr(text1, "wordwrap", text1_wordwrap_value = true);
The elements are being detected as and forced to SVG. There must be some code in svelte that does this which we need to skip for namespace foreign
When trying this code:
the text widget does not wrap and the plainTextEdit is not readonly.