Elm's Virtual DOM does not work well with Chrome extensions (Issue). This repository aims to resolve it by following process.
- Gather information about how extensions break DOM (insert, wrap, etc.)
- Make a patch for
elm/virtual-dom
- Try online with problematic extensions enabled/disabled
This table describes where and when an element is inserted, thanks to the discussion in the discourse thread. More informarion is still welcome.
Plugin (Users) | Where in <body> |
When | Workaround (keep enabled) | Workaround (disable) | |
---|---|---|---|---|---|
Google Translate (10,000,000+) | middle | translate the page | <meta name="google" content="notranslate"> in <head> |
||
Google Translate | bottom | select words | rough patch, use Browser.element |
||
Grammarly (10,000,000+) | middle | focus on <textarea> |
data-gramm_editor="false" |
||
Dark Reader (1,763,020) | middle (sometimes) | laod | make <style> the last child, avoid using <style> in <body> |
||
ChromeVox (161,918) | top | load, focus on something | rough patch, use Browser.element |
||
Viber (133,220) | top, bottom | load | rough patch, use Browser.element |
Note:
- For "Where in
<body>
" Column,top
andbottom
breaksBrowser.application
andmiddle
breaks bothBrowser.application
andBrowser.element
.middle
contains modifications to all descendant elements in the<body>
. - Some of the extensions insert elements in
<head>
or after<body>
. They are excluded from this list because it has no harm.
You can test the patched version of elm/virtual-dom
. About the patch, see more details here.
npm install
npm run build
This will build:
- patched version of
elm/virtual-dom
simple.js
fromsrc/
using the original versionsimple-patched.js
fromsrc/
using the patched version
npm test
This test uses puppeteer and breaks DOM in various patterns without real Chrome extensions.
For each test case,
- An element is inserted/removed via ports when a button is clicked.
- Elm will update Virtual DOM. See the source to find where in the DOM is updated in each case.
npm run test:extensions
This test coveres problematic cases of well-known extensions.
Since this test uses the real extensions, it cannot be covered by puppeteer. You need to see the result on your Chrome. Turn on and off the your extensions to see how the results change.
Here is a simple patch (thanks to a discourse comment) for Browser.application
.
root_id=root # Note: <div id="$root_id"> must exist before Elm.Main.init()
cat elm.js\
| sed "s/var bodyNode = _VirtualDom_doc.body;/var bodyNode = _VirtualDom_doc.getElementById('$root_id');/"\
| sed "s/var nextNode = _VirtualDom_node('body')(_List_Nil)(doc.body);/var nextNode = _VirtualDom_node('div')(_List_Nil)(doc.body);/"\
> elm-patched.js
Note: This is just a workaround, NOT a fix. For Browser.application
, the root should be always <body>
element. This is by design.
Note: This will be no use once this patch is merged.