Last active
July 25, 2023 12:45
-
-
Save developit/3e807962630ddbd4977cbd07b597f24f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { options } from 'preact'; | |
// Fix Preact rendering when Google Translate breaks the DOM | |
const FONT_AS_TEXT = { | |
localName: { | |
value: null | |
}, | |
nodeType: { | |
value: 3 | |
}, | |
data: { | |
get() { | |
return this._data; | |
}, | |
set(v) { | |
v += ''; | |
if (v === this._data) return; | |
const t = document.createTextNode(this._data = v); | |
this.parentNode.replaceChild(t, this); | |
this.__v.__e = t; | |
} | |
} | |
}; | |
function check(child, ref) { | |
if (ref && ref.nodeType === 3 && child) { | |
let intercept = child.localName === 'msreadoutspan'; | |
if (!intercept && child.localName === 'font') { | |
for (let i in child) { | |
if (i.startsWith('_gt_')) { | |
intercept = true; | |
break; | |
} | |
} | |
} | |
if (intercept) { | |
ref._font = child; | |
child._data = ref.data; | |
Object.defineProperties(child, FONT_AS_TEXT); | |
} | |
} | |
} | |
const ib = Element.prototype.insertBefore; | |
Element.prototype.insertBefore = function(child, ref) { | |
check(child, ref); | |
return ib.apply(this, arguments); | |
}; | |
const rc = Element.prototype.replaceChild; | |
Element.prototype.replaceChild = function(child, ref) { | |
check(child, ref); | |
return rc.apply(this, arguments); | |
}; | |
const oldDiffedHook = options.diffed; | |
options.diffed = vnode => { | |
if (vnode.type === null && vnode.__e) { | |
const font = vnode.__e._font; | |
if (font) { | |
vnode.__e = font; | |
font.__v = vnode; | |
font.data = vnode.props; | |
} | |
} | |
if (oldDiffedHook) { | |
oldDiffedHook(vnode); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@oshell This worked for us, but after spending a lot of time debugging this is the approach I found worked for Google translate:
Some of my observations:
child.innerText = ref.innerText;
inside the custominsertBefore
prototype doesn't seem to actually be doing anything. Simply early returning and preventing something from happening ininsertBefore
was enough for the duplication to go awayreplaceChild
function to trigger at all using default Chrome Google Translate. Was that included in yours for a different translation tool?diffed
top level if statement was never being triggeredObviously none of that is reassuring so I was curious what you ran into that caused you to add those so I can be sure I'm not missing anything.