I'm working on a bookmarklet which will let users to write on any input fields in our language. We choose Ctrl+M for switching layout between default and our language (Inspired by Wikipedia). It was working fine in almost every website with chrome. When we started checking with Firefox we found that it only fails in Facebook.
Moreover, Facebook catches the Ctrl+M from outside the window
scope. Like, form the address bar, search bar, firebug console, etc.
I've tried with raw javascript, jQuery and also with the jQuery Hotkeys plugin by John Resig but no luck :(
Here is a version that I had tried. You can run it on your Firebug console for testing purpose -
(function(){
var noConflictMode = false;
if(typeof $ !== 'undefined') noConflictMode = true;
if(typeof jQuery === 'undefined') {
var root = (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]);
var ns = document.createElementNS && document.documentElement.namespaceURI;
var script = ns ? document.createElementNS(ns, 'script') : document.createElement('script');
script.type = 'text/javascript';
script.onreadystatechange = function () {
if (this.readyState == 'complete') test();
}
script.onload= test;
script.src= 'https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.min.js';
root.appendChild(script);
} else {
test();
}
function test() {
if(noConflictMode) jQuery.noConflict();
jQuery(window).on('keydown keyup keypress', function(e){
e.preventDefault();
// For Firefox
e.stopPropagation();
// Extra effort :|
e.stopImmediatePropagation()
e.cancelBubble = true;
console.log(e);
return false;
});
}
})();
You can NOT do that on client-side web for security reasons, you can code anything in JS or JQ or any language you want but MOZ never will take care of your code.
Take care, one thing is that the browser "compile" your code and work with it, and another thing is that you can change the browser itself. For that reasons there's the "add-on".
For example, you can't change the kernel of Visual Studio programming in V.S. :D
BUT...
... you can ask to the user re-bind the keys, you have 3 ways to do that:
1) installing a MOZ add-on (or your own addon)
2) Working with: http://mxr.mozilla.org/seamonkey/source/dom/public/idl/events/nsIDOMKeyEvent.idl
3) installing a shortcut keyb at OS level with higher priority than the App (in this case, MOZ) (you can do it with C#). Alt+tab combination is an example of high level shortcut, or "Prnt Scrn"
There is NO way to do that with about:config, neither.
Maybe this url can help you, but i suggest you try asking for changes in MOZ and not asking for Javascript code.
http://www-archive.mozilla.org/unix/customizing.html#keys
Related
There are a lot of answers related to this question, but most of those answer information are deprecated years ago by chrome browser.
I need a working example, how to detect google chrome browser addon/extension which is installed in users browser using (javascript/any method).
If i use event detection, there is a addon called " Luminous:
JavaScript events blocker" which blocks all event detection and bypass
the events generated by javascript.
<script>
(function(w, u){
var intervalLuminous = null;
var isLuminousInstalled = false;
var setLuminousDetected = function(){
isLuminousInstalled = true;
alert('Luminous: JavaScript events blocker installed!');
}
var checkLuminous = function(){
if (document.getElementById('luminous-options') || document.getElementById('luminous-data')) {
clearInterval(intervalLuminous);
setLuminousDetected();
}
}
intervalLuminous = setInterval(function(){
checkLuminous();
}, 10);
if(!intervalLuminous){
setLuminousDetected();
}
})(window, undefined);
</script>
I'm working on building a javascript widget that users will be able to include on their websites which will display data from our web application. The main file which a user will include w1.js contains the following:
var MYLIBRARY = MYLIBRARY || (function(){
var _args = {};
var jQuery;
function main(){
//simply display loaded jquery version as a test
jQuery('#mylibrary-w1-content').text(jQuery.fn.jquery);
}
function scriptLoadHandler(){
jQuery = window.jQuery.noConflict(true);
main();
}
return {
init: function(Args){
_args = Args;
if(window.jQuery === undefined || window.jQuery.fn.jquery !== '3.3.1'){
var script_tag = document.createElement('script');
script_tag.setAttribute("type", "text/javascript");
script_tag.setAttribute("src", "//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js");
if(script_tag.readyState){
script_tag.onreadystatechange = function(){ // for old versions of ie
if(this.readyState === 'complete' || this.readyState === 'loaded'){
scriptLoadHandler();
}
};
} else {
script_tag.onload = scriptLoadHandler;
}
(document.getElementsByName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
jQuery = window.jQuery;
main();
}
}
};
/* END OF LIBRARY
*******************************************************************************/
}());
The code which users include on their website is as follows:
<script src="//thewebsite.com/widgets/w1.js"></script>
<script>
window.addEventListener('load', function(){MYLIBRARY.init(["somevalue"]);}, false);
</script>
<div id="mylibrary-w1-content"></div>
Everything is functioning as expected in chrome, however ie and firefox (thought this was just an ie issue until it didn't work in firefox, thought that was odd) return an error message in the console ReferenceError: MYLIBRARY is not defined.
My initial thought was that w1.js had not completed loading before the call to MYLIBRARY, however the addEventListener('load') appears to be functioning as expected, unless I've missed something or am doing something incorrectly.
Any Ideas?
After a bit of additional troubleshooting I discovered what was causing this issue. It was not related to javascript. The url where w1.js was being loaded from is an internal test site which uses a self signed ssl cert. The reason this was not working in firefox or ie, is because exceptions for this certificate did not exist in firefox or ie, therefore when the call was made, the file was never returned. Adding the exceptions solved the issue.
I'm trying to create a script which will run when any browser console is opened or closed. Is there any way to detect if the browser console in all browsers (Firefox/IE/Chrome/Safari/Opera) is open or not via JavaScript, jQuery, or any other client-side script?
If you are willing to accept an interference for the user,
you could use the debugger statement, as it is available in all major browsers.
Side note: If the users of your app are interested in console usage, they're probably familiar with dev tools, and will not be surprised by it showing up.
In short, the statement is acting as a breakpoint, and will affect the UI only if the browser's development tools is on.
Here's an example test:
<body>
<p>Devtools is <span id='test'>off</span></p>
<script>
var minimalUserResponseInMiliseconds = 100;
var before = new Date().getTime();
debugger;
var after = new Date().getTime();
if (after - before > minimalUserResponseInMiliseconds) { // user had to resume the script manually via opened dev tools
document.getElementById('test').innerHTML = 'on';
}
</script>
</body>
devtools-detect should do the job. Try the simple demo page.
devtools-detect → detect whether DevTools is open, and its orientation.
Supported Browsers:
DevTools in Chrome, Safari, Firefox & Opera
Caveats:
Doesn't work if DevTools is undocked (separate window), and may show a false positive if you toggle any kind of sidebar.
I don't think it is directly possible in JS for security reasons.But in here
they are claiming that it is possible and is useful for when you want something special to happen when DevTools is open. Like pausing canvas, adding style debug info, etc.
But As #James Hill tell in this, I also thinks even if a browser chose to make this information accessible to the client, it would not be a standard implementation (supported across multiple browsers).
Also can also try this one also here.
It's not possible in any official cross browser way, but if the occasional false positive is acceptable, you can check for a window.onresize event. Users resizing their windows after loading a page is somewhat uncommon. It's even more effective if you expect users will be frequently opening the console, meaning less false positives as a percentage.
window.onresize = function(){
if ((window.outerHeight - window.innerHeight) > 100) {
// console was opened (or screen was resized)
}
}
Credit to https://stackoverflow.com/a/7809413/3774582. Although that question is chrome specific, the concept applies here.
To expand on this, if you need a very low tolerance on false positives, most window resizes will trigger this event dozens of times because it is usually done as a drag action, while opening the console will only trigger this once. If you can detect this, the approach will become even more accurate.
Note: This will fail to detect if the console is already open when the user visits the page, or if the user opens the console in a new window.
(function() {
'use strict';
const el = new Image();
let consoleIsOpen = false;
let consoleOpened = false;
Object.defineProperty(el, 'id', {
get: () => {
consoleIsOpen = true;
}
});
const verify = () => {
console.dir(el);
if (consoleIsOpen === false && consoleOpened === true) {
// console closed
window.dispatchEvent(new Event('devtools-opened'));
consoleOpened = false;
} else if (consoleIsOpen === true && consoleOpened === false) {
// console opened
window.dispatchEvent(new Event('devtools-closed'));
consoleOpened = true;
}
consoleIsOpen = false;
setTimeout(verify, 1000);
}
verify();
})();
window.addEventListener('devtools-opened', ()=>{console.log('opened')});
window.addEventListener('devtools-closed', ()=>{console.log('closed')});
Here is a code that worked for me.
This solution works like a charm
https://github.com/sindresorhus/devtools-detect
if you are not using modules - disable lines
// if (typeof module !== 'undefined' && module.exports) {
// module.exports = devtools;
// } else {
window.devtools = devtools;
// }
and result is then here
window.devtools.isOpen
I for my project use the blur event.
function yourFunction() {}
window.addEventListener('blur',(e)=>{e.preventDefault(); yourFunction()})
This will execute yourFunction when the window loses focus.
For instance when someone opens the DevTools.
Okay seems like it also fires when you try to access a different window... so maybe not the best solution.
Maybe pair it with looking at the width of the browser.
If it chainged you can be pretty sure about it I think
Have anybody out there found a simple way of detecting whether the browser supports the transitionend event or not in vanillaJs, especially in a way that actually works in all major browsers? :(
I have found this unanswered thread in here: Test for transitionend event support in Firefox, and quite a lot of almost working hacks.
Right now I am bulk adding eventlisteners to all the vendor prefixes, and it kind of works out (even though I think it is a hideous approach that hurts my eyes every time I look at it). But IE8 and IE9 does not support it at all, so I need to detect those two, and treat them separately.
I would prefer to do this without browser sniffing, and definitely without huge libraries/frameworks like jQuery
I have made a jsfiddler snippet that illustrates my problem. There is a button that spawns a dialog. When the dialog is removed by clicking close, it is transitioned in top and opacity, and after ended transition it is supposed to display=none. But if the transitionend is never fired (like in IE8 and IE9), the dialog is never removed, making it cover the show dialog button, destroying the UX. If I could detect when transitionend is not working, I could just set the display=none when closing for those browsers.
http://jsfiddle.net/QJwzF/22/
window.listenersSet = false;
window.dialogShouldBeVisible = false;
window.showMyDialog = function () {
var myDialog = document.getElementById('dialog'),
myClose = document.getElementById('close');
if (!listenersSet) {
if (!window.addEventListener) { // IE8 has no addEventListener
myclose.attachEvent('onclick', function () {
hideMyDialog();
});
} else {
myClose.addEventListener('click', function () {
hideMyDialog()
});
['webkitTransitionEnd','oTransitionEnd', 'otransitionend', 'transitionend'].forEach(function (eventName) {
myDialog.addEventListener(eventName, function (e) {
if (e.target === myDialog && e.propertyName === 'top') { // only do trigger if it is the top transition of the modalDialog that has ended
if (!dialogShouldBeVisible) {
myDialog.style.display = 'none';
e.stopPropagation();
}
}
});
});
}
listenersSet = true;
}
myDialog.style.display = 'block';
myDialog.style.top = '15px';
myDialog.style.opacity = '1';
dialogShouldBeVisible = true;
}
window.hideMyDialog = function () {
var myDialog = document.getElementById('dialog'),
myClose = document.getElementById('close');
myDialog.style.top = '-5%';
myDialog.style.opacity = '0.1';
dialogShouldBeVisible = false;
}
It is working in Opera, Firefox, Chrome and IE10, but not in IE8 and IE9 (afaik)
If I did a bad job explaining my problem, please let me know, and I will try do a better job! :)
Copied from bootstrap transition, it not only returns true if browser supports transition but also returns proper name of event
function transitionEnd() {
var el = document.createElement('div')//what the hack is bootstrap
var transEndEventNames = {
WebkitTransition : 'webkitTransitionEnd',
MozTransition : 'transitionend',
OTransition : 'oTransitionEnd otransitionend',
transition : 'transitionend'
}
for (var name in transEndEventNames) {
if (el.style[name] !== undefined) {
return transEndEventNames[name];
}
}
return false // explicit for ie8 ( ._.)
}
Hope this helps.
EIDT:
I modified a little bit default bootstrap function so it doesn't return object but string.
I would definitely use this small script available on Github.
It's listed among Modernizr "Cross-browser polyfills" page so it can be trusted but Modernizr itself is not required.
The examples in the Github page of the script are written using jQuery (and I can't understand why) but jQuery is also not required as it's written in vanilla js.
Like so you'll have a useful whichTransitionEnd method available. I can't test it right now being on my laptop without IE8/IE9 available but I guess that this method will return false (or anything falsy) in those browsers.
var transition = transitionEnd(box).whichTransitionEnd();
// return for example "webkitTransitionEnd"
It will then be quite easy to target those browsers where transitions (and thus transitionend events) are not supported. Hope this will be a nudge in the right direction.
EDIT
After tweaking with the above code the OP came up with a much shorter version of the original script. It saves a good deal of bytes and only detects support for this event, and, in case it's supported returns the name of the event itself.
You can find it here as a gist and read more about it in the comments to this answer.
I want to use Ctrl+Enter to submit the Google+ reply but it does not work when I send a 'Click' event to the submit button. This is a chrome plugin for plus.google.com.
document.onkeydown=function(e){
if(e.ctrlKey&&e.keyCode==13){
div_id=document.activeElement.id;
div_id=div_id.substr(0,3);
editorid=div_id.substr(0,2)+String.fromCharCode(div_id.charCodeAt(2)-1);
postbuttonid=editorid+'.post';
console.log(postbuttonid);
postbutton=document.getElementById(postbuttonid);
evt=document.createEvent("MouseEvents");
evt.initEvent("click", true, true);
postbutton.dispatchEvent(evt);
}
}
I suggest you use jQuery:
jQuery("#:2s.post").click();
The above code should work assuming that, as one of your comments describes, the button you want to click has the id ":2s.post".
I hope that works for you. If you're unable to include jQuery directly, you could try something like:
/*--- Create a proper unsafeWindow object on browsers where it doesn't exist
(Chrome, mainly).
Chrome now defines unsafeWindow, but does not give it the same access to
a page's javascript that a properly unsafe, unsafeWindow has.
This code remedies that.
*/
if (typeof unsafeWindow === "undefined") {
unsafeWindow = ( function () {
var dummyElem = document.createElement('p');
dummyElem.setAttribute ('onclick', 'return window;');
return dummyElem.onclick ();
} ) ();
if(typeof unsafeWindow === "undefined") {
unsafeWindow = window;
}
}
// END PROPER unsafeWindow
var script = unsafeWindow.document.createElement("SCRIPT");
script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js';
script.type = 'text/javascript';
unsafeWindow.document.getElementsByTagName("head")[0].appendChild(script);
script.addEventListener('load', function(){
jQ = unsafeWindow['jQuery'];
$ = jQ.noConflict(true); // keep jQuery local so you don't accidentally override/overwrite any variables
requiresjQuery($);
}, false);
In which case, your code would actually look more like:
function requiresjQuery($) { // put any code in here that requires jQuery; I actually recommend putting all of your code in here.
$("#:2s.post").click();
}
try document.forms.yourForm.submit();