Detect if beforeinput is supported - javascript

I made use of the https://github.com/jaridmargolin/formatter.js library in my project and discovered it is not working properly on mobile devices.
My research showed that this is due to it's use of keypress which is evil and should not be used. So I decided to modify it and use "beforeinput" whenever available. And here lies the problem, how do I detect whether it is available?
I tried this methode: https://stackoverflow.com/a/2877424/13987708
But it doesn't work.
My Internet search only showed me a bunch of different veriations of the same methode when checking for detecting supported events in a browser. And I can see that this method most of the times works. it even works for the "input" event, but unfortunatly not for the "beforeinput" event.
I would love to find a way that does not rely on the user agent, as that is, so I'm told, very unrelyable.
// EDIT
Well, I did research the issue, I even say so in my question :duh:...
The situation is that "keypress" is deprecated and should not be used anymore, in fact in Chrome for Android it doesn't even fire anymore.
The above mentioned plugin to format user input relies on the methode, though.
So I went ahead and replaced it with the "keyup" methode, which indeed fires in Chrome for Android, but only gives a keyCode of 229, so it doesn't work either.
I dug a bit deeper into this whole keyboard events and found that modern browsers support the "beforeinput" event (https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/beforeinput_event).
Which is awesome, it gives you so much mor information about the interaction between the user and your input.
So I adapted the formatter to use the "beforeinput" event instead of "keypress", but my project has to support IE, which does not support "beforeinput".
That's why I need a way to detect if the browser supports this event, and use either the "keypress" or the "beforeinput" depending on the capabilities of the users browser.
And I am aware that a browser might support functionality which the user won't use, but it's not relevant for this use case, I just need to know if the browser will fire the "beforeinput" event or not.

Related

React trigger event through mouse click on span [duplicate]

I know there are lots of javascript plugins and libraries to allow users to pick emojis for text inputs, but windows and mac already have native emoji pickers (⊞ Win. or CTRL⌘Space), Is there a way for me to open these native emoji pickers when a user clicks in a text field instead of installing plugins in my website?
I already tried emulate button key press, but it didn't work at all.
Short answer is no.
In order to access any OS feature from javascript, you need a corresponding browser API to support.
AFAIK, there isn't an API for that. There's a discussion here which suggests adding <input emoji /> to standard but seems no traction gained.
Edit: Below is my original answer, revised. Comments pointed out I was focusing on the wrong aspect of the question, I totally agree.
However, the OP obviously has some wrong idea about what you can do in javascript to leverage browser ability. So I think it's still worth clarification.
You can't send arbitrary emulated keyboard event from js and hoping the OS will respond. Were it possible, it'd be a severe security issue on browser's part. Imagine open a website and it fires a series of keyboard event to your OS and wipes out your desktop (totally feasible through shortcuts).
You need to understand the runtime env inside the browser is basically isolated from the one of native OS. Whatever OS feature that's accessible to your javascript is totally up for browser vendors to decide. For security reason, they are super careful in making these decisions.
Also, make a distinction on "what browser can do", and "what browser allows you to do in js". Seeing Chrome has an "Emoji & Symbols" context menu item, doesn't necessarily mean it decides to grant you the same ability in js.
To further clarify why the emulated keyboard event is fundamentally different from the native one, I include a graph here. The blue arrow is how emulated keyboard event flows. The farthest place it can reach is the browser's internal event bus. It never got a chance to reach the OS event bus, so no way to notify native emoji picker.

How to detect "enter-key press in input clicks next button" behavior using JavaScript in IE 8-10

I am trying to "feature detect" IE's behavior when pressing enter in an input box that has a button element next to it (when they are not in a form element).
I'm saying IE's behavior because no one else fires a click event on the next button when pressing the enter-key while the input is focused.
Related question where the first awnser describes why IE behaves like this:
IE bug triggers click for 2 buttons?
JS-Fiddle where I try to simulate the key press via jQuery.Event and .trigger:
http://jsfiddle.net/DbVrn/
Behavior of said js-fiddle in IE:
When opening the page, the input gets focus, and then we try to simulate pressing of the enter-key.
The simulated enter-key does nothing, hence the input remains focused and red.
If you manually press enter while the input is focused, the button will become focused and green.
The problem i have with my current attempt to detect this feature is that:
$("input").trigger(jQuery.Event("keypress", { which: 13 }));
does not actually do the same as manually pressing the enter-key while the input is focused.
How can I successfully simulate the enter-key so that my test for this behavior is possible?
Or is there another way i can test for this behavior?
Edit: Updated title to more clearly state that this needs to be tested via javascript, and that the test needs to work in IE from version 8 to 10. Unless anyone else can provide a way of testing this, I will conclude that I need to use user-agent sniffing to see if browser is IE and choose code-path based off that.
Neither by using jQuery's trigger method nor by using the native methods it is possible to simulate key presses in the way that you would like to. The real and simulated key presses can both be captured, but the simulated key presses do not trigger the entire chain of event handlers that are caused by a real key press. This is easily demonstrated by putting this line above your trigger
$("input").keypress(function(event) { alert(event.which); });
As you can see the capture works fine, for both simulated and real key presses, while the difference between the handling of those two key presses obviously remains.
It also does not matter what you do with your keypress event objects. You may add a keyCode, which the real keypresses in IE have, but this will not change this. It seems nothing will. Unfortunately I cannot find any documentation explaining why, though this problem has been around for a while
http://forums.asp.net/t/1478871.aspx/1
So there seems to be no way from within the browser. You would have to do it from without. You could use something like InternetExplorerDriver for that.
Instead of feature detecting I would recommend simply recording which user agents have this 'feature'. Since Microsoft is usually pretty bend on backwardscompatibility it is unlikely they will change the behavior of an enter keypress on an input field in future version.
http://code.google.com/p/selenium/wiki/InternetExplorerDriver
Simulating key presses that change input/textarea fields
Using the TextEvent method it is possible in some browsers (e.g. chrome) to send text, including new line, to an input or textarea field, but this will not work in any version of IE up to version 10 as demonstrated by this fiddle:
http://jsfiddle.net/qz7kV/1/
It seems there is no way to test for this behavior via JavaScript.
I have tested IE 8, 9 and 10 and confirmed they all behave this way.
So for now, i am going to combine some ideas from
Javascript IE detection, why not use simple conditional comments? and
http://tanalin.com/en/articles/ie-version-js/ to create a test for IE that will work reliably as long as IE does not remove support for conditional compilation comments.
var ie = (/*#cc_on!#*/false && (function(){
var div = document.createElement("div"),
list = div.getElementsByTagName("br"),
version = 3;
do {
div.innerHTML = "<!--[if gt IE " + (++version) + "]><br><![endif]-->";
} while(list[0]);
return (version > 4 ? version : 10);
}()));
The ie variable will be the browser version in Internet Explorer, and will be false in other browsers.
I don't see a reliably way to trigger the bug from JavaScript alone. You have several other options:
Install IE in a VM and use a UI robot to drive the test. That takes a lot of effort but will reliably trigger the bug.
There are companies which offer remote testing; they use SSH tunnels to access a server on your side and can test your site against many different versions of IE. This is pretty easy to set up technically but might be hard to get because of company policies, FUD and politics. Google for "test web site with many different browsers"
Test it once manually and when it works, write a test case which just checks that the code is there (i.e. a test that fails when the JavaScript file or page source doesn't contain a certain fixed string). Pro: Very easy to set up, Con: Breaks easily
Just test it once and then rely on inertia (i.e. that no one else will touch that code for years).

onselectionchange Javascript event in webview

In my Android app I'm attaching a handler for the Javascript onselectionchange like this:
$(document).on('selectionchange',function(ev){
alert('Text has been selected');
});
This is supposed to be fired when the user selects something (like text) or the selection changes, however it is fired on tap. Does anyone know the reason of this behavior? (Something like this is working in iOS)
"onselectionchange" event is not a cross-browser feature.
AFAIK, it's only Trident (iexplore) and recent versions of webkit (and hence webview) that support text selection events.
That being said, could it be that the version of webkit present on the iOS you tested is more recent than your Android's version?
Also consider that though they both render with webkit, they use totally different javascript engines, hence potentially different behaviour.

Global Hotkey for Firefox

Is there a way to add hotkeys (such as the media buttons) for the webbrowser?
This would need to cause a javascript event.
I except a firefox extension is required and i am ok if the solution requires greasemonkey as well (i seen growl use them both for javascript interaction. But thats javascript->pc not the other way around)
-edit- is this not possible ATM?
Firefox supports something called an AppCommand event. On Windows and Linux, only 7 commands are supported: Back, Forward, Reload, Stop, Search, Bookmarks and Home.
To implement extra commands, supported would have to be added to widget/src/windows/nsWindow.cpp and widget/src/gtk2/nsWindow.cpp to generate those additional types of AppCommand event. These events could then be intercepted by an extension to perform custom actions.
On Android, a different set of events are supported: Clear, VolumeUp, VolumeDown, Menu, Search. I don't know whether these events are used by Fennec.
For completeness, OS/2 builds of Firefox support Back, Forward, Reload and Stop.

Opera: Detecting back, forward, refresh and close events

I'm currently working on a jQuery plugin that tracks a visitors mouse behavior. Movements, clicks, scrolling and resizing are all recorded and sent, via Ajax, to a location where this data is parsed and stored.
Originally, the data is sent to a script when the user leaves the page. By 'leaves' I'm referring to refreshing, going back and forth though history, closing the window/tab and going to a different address.
The solution works in all browsers EXCEPT for Opera. I'm using jQuery's 'unload' event which isn't supported by Opera at all. Neither is onbeforeunload or onunload.
The question is, how do I implement this kind of functionality for Opera browsers?
One solution I had was to make special use of a 'polling' feature I created. This feature allows you to specify an interval which pushes the content to the server every 'x' seconds. Setting this to 1 second specifically for Opera browsers would probably solve this issue, but it's an awful amount of overhead and the requests aren't always completed in sequence, etc ...
Any suggestions or am I only stuck with the above option?
Thanks!
I suppose I could just link you guys to the plugin source. http://www.thedrunkenepic.com/junk/jquery.mousalytics.js
Regarding the code linked above, adding:
if(window.opera)
{
options.interval = 1;
}
On line 89 works great. My only concern is overhead, so I'm still looking for a more elegant solution.
According to http://bytes.com/topic/javascript/insights/799229-browser-quirk-onload-onunload-do-not-fire-back-forward-refresh-opera, Opera never really fires onload / onunload events, so functionality like this isn't possible without hacks.
http://dev.opera.com/articles/view/efficient-javascript/?page=4 seems to confirm this, and basically states that opera tries to maintain the state of the page across requests.
On further investgation, http://unitehowto.com/Onunload indicates that it might be possible with opera.io.webserver.addEventListener('_close', onunload, false); (where onunload is a previously defined function), however it also indicates that this functionality is not consistent across all versions of opera, and might not work at all.
I think that your best option is probably to use the polling option for Opera, or possibly use a server-side check for the current page and where it falls in the history queue.
Does adding this line of JavaScript work for you?
history.navigationMode = 'compatible';
Source: http://www.opera.com/support/kb/view/827/
I've had the same problem and this saved my day:
if( typeof(opera) != 'undefined' )
{
opera.setOverrideHistoryNavigationMode( 'compatible' );
history.navigationMode = 'compatible';
}
More info about this problem can be found at: http://www.opera.com/support/kb/view/827/

Categories