Code Journey #9
KDE
- Simplified Chinese translation update
- Unsplash Picture of The Day provider
- JuK slider's HiDPI support
- JuK single instance start up
- HiDPI development document
- Kimpanel system tray mode
openSUSE
- Update python-PyMuPDF package
KDE
openSUSE
Note: we are only talking about Google Translate function in Chrome or Chromium based browsers. Other translate plugins or software don't necessarily work with this solution. And this solution doesn't solve all issues, just a part of them.
You have a component:
const Button = ({children, icon, isLoading, ...rest}) => (
<button {...rest}>
{icon}
{children}
{isLoading && <Loader/>}
</button>
)
const Test = () => <Button icon="+">Hello World</Button>
Which is rendered to:
<button>+Hello World</button>
If an element (<button>
in this case) contains multiple rendered string variables, they become text nodes in React's VDOM and HTML DOM. However, Google Translate doesn't care about text nodes and wrap them inside a <font>
element:
<button><font>+你好世界</font><button>
Since they are not text nodes anymore, synchronization between React and DOM was broken. The button content will not be updated anymore.
Simply avoid this situation. Write every {variable}
inside an element, as the only child.
const Button = ({children, icon, isLoading, ...rest}) => (
<button {...rest}>
<span className="button__icon">{icon}</span>
<span className="button__text">{children}</span>
{isLoading && <Loader/>}
</button>
)
const Test = () => <Button icon="+">Hello World</Button>
Now every variable is synchronized with the <span>
element, not text nodes. Inserting <font>
elements doesn't break the connection.
Another situation is that when you mix text nodes with elements.
<p>
Copyright 2016-{new Date().getFullYear()}
</p>
Should be converted to:
<p>
<span>Copyright 2016-</span>
<span>{new Date().getFullYear()}</span>
</p>
Just make sure: a text node or string variable must be the only child of an element.
Another issue is that the click event target will change. It might be <font>
elements instead of <button>
. Carefully check everywhere you use e.target
, considering they might not be the button, input or other elements you expected.
A further suggestion is to avoid using any e.target
reference. Here is a piece of legacy code:
const {sizes, onChange} = this.props
return (
<div>
{sizes.map(size => (
<button
key={size}
name="size"
value={size}
onClick={e => this.props.onChange(e.target.value)}>
{size.toUpperCase()}
</button>
))}
</div>
)
Can be changed to:
const {sizes, onChange} = this.props
return (
<div>
{sizes.map(size => (
<button
key={size}
name="size"
value={size}
onClick={e => this.props.onChange(size)}>
{size.toUpperCase()}
</button>
))}
</div>
)
In this case, you usually cannot modify the component as you want.
You can try to use <span>your string</span>
instead of "your string"
as component properties.
Report to the library maintainers and make a PR with above methods.
Some components doesn't support inner wrappers, like <option>
. If you put <span>
inside <option>
, React will give you warnings in console, even though the rendering works. So you probably don't want to do it.
For example you have:
<select>
{fruites.map(f => <option value={f.name}>{f.name} - {f.price}</option>)}
</select>
Change it to:
<select>
{fruites.map(f => {
const label = f.name + ' - ' + f.price;
return <option value={f.name}>{label}</option>
})}
</select>
Even if you do all above, something can still go wrong. If you don't have time to waste and just want to disable Google Translate, it is simple:
<body class="notranslate">
...
</body>
To avoid too many short posts, I will summarize my work weekly in future. Post date will be the every Sunday.
adobe-sourcehansans-fonts
and adobe-sourcehanserif-fonts
with additional provides for languagesThis is the first post. Free Software is a meaningful thing. By recording what I have done, motivate me to keep going.