-
Notifications
You must be signed in to change notification settings - Fork 437
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
event doesn't trigger #1758
Comments
Actually the event is dispatched, but does not bubble up. As I said, it works if I load the extension in chrome developer mode, or in Greasemonkey. |
Can you please post some example code that isn't working? |
I fixed this with the workaround posted here: facebook/react#11488 (comment) But I still don't know why it works without the hack/workaround in Greasemonkey or the script loaded directly in developer mode. |
Here is a test case: // ==UserScript==
// @name Test React Input Event
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://react.dev/
// @icon https://www.google.com/s2/favicons?sz=64&domain=react.dev
// @grant GM_registerMenuCommand
// ==/UserScript==
(function() {
'use strict';
GM_registerMenuCommand("change search value (naive)", () => {
const input = document.getElementById("docsearch-input");
if (!input) {
console.log("no input");
return;
}
input.value = "test";
input.dispatchEvent(new Event('input', { bubbles: true }));
});
GM_registerMenuCommand("change search value (hack)", () => {
const input = document.getElementById("docsearch-input");
if (!input) {
console.log("no input");
return;
}
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(input), "value").set.call(input, "test");
input.dispatchEvent(new Event('input', { bubbles: true }));
});
})(); Go to https://react.dev/, set focus on the search field, and then run one of the menu commands. React does some shit by replacing the Thoughts about GM: if it uses FF's UserScript API to create a sandbox, the script probably receives an unmodified element with the original |
The event actually bubbles up as can be seen by adding a listener on
Sounds plausible. Personally, I prefer the old document.execCommand to trigger the site's handlers reliably: input.focus();
if (input.value) input.select();
document.execCommand('insertText', false, 'test'); |
This command is deprecated, so no longer recommended.
It works even on Chrome developer mode (with manifest v3, didn't tried with v2). I thought about sandboxing, but I tried every Tampermonkey sandbox setting and still doesn't work. https://www.tampermonkey.net/documentation.php?locale=en#meta:sandbox |
A new replacement API isn't yet created, so execCommand will work for many years more, maybe even decades... Note that execCommand adds to the undo stack of the input element, which is especially important in a textarea or contenteditable, which both have a multi-undo stack, and we can't imitate it by setting the value directly or by adding a DOM element inside. |
BTW the first command in @7nik's comment starts working in Violentmonkey after adding |
uses userScripts API if possible. Therefore this will work in Firefox only.
will work at Firefox (falls back to the userScripts API) and also Chrome, but you have to set "Sandbox Mode" to "All" first. Warning: "DOM" scripts are injected into the extension context and can install new scripts by modifying the extension storage. |
In TM, the first command forks with So, executing the script in ISOLEATED_WORLD allows it to get the original unmodified element.
What do you mean by this? Auto-converting userscript into extension? Then it, of course, will work - the script is executed in ISOLEATED_WORLD. I am personally not sure that this issue is in the Userscript manager's responsibility - any lib can mess up with elements/type prototypes, and here is the solution - execute the script in ISOLEATED_WORLD:
P.S.: I'm a bit too late. |
Using @7nik's code above, how would I set the value of a contenteditable div (eg: message box in Instagram messages)? I assume it's not supposed to be "value" since it's a div, right? What should it be? Because I'm getting this error: "Uncaught TypeError: Cannot read properties of undefined (reading 'set')" |
For contenteditable elements, it's innerHTML or textContent if you set a plain text. They can likely be used directly. |
Using either of those 2 things doesn't work with the contenteditable div element in Instagram messages on the web? I assume it's because it's using react and therefore doesn't detect those kind of DOM changes. Any suggestions? |
Expected Behavior
For example:
element.dispatchEvent(new Event('change', {bubbles:true}))
Event should trigger. With Greasemonkey the event is triggered ok.
Also works if the script is loaded in developer mode.
Actual Behavior
The events are not triggered with Tampermonkey.
Specifications
The text was updated successfully, but these errors were encountered: