ondevicemotion in Chrome desktop returns true - javascript

I am using a "shake" function from github - and it has a detection that is browser-based javascript.
//feature detect
this.hasDeviceMotion = 'ondevicemotion' in window;
This though yields true even on Chrome on OS X.
It feels strange, since I am not willing to shake my monitor on my desktop.
Safari on OS X gives me "false" in return when testing.
I have searched but not been able to find out why Chrome decided to take this path. It bugs me.
Is there a better way to make this detection? Not all "mobile devices" has shake as well.. or does not let the browser have that capability, as it does not seem to work in windows phones.

not really sure about your question and as well, I am just digging into its functionality, however you could use something like
X : <span id="varx"></span>
Y : <span id="vary"></span>
Z : <span id="varz"></span>
<script>
window.ondevicemotion = function(event){
var accelerationX = event.accelerationIncludingGravity.x;
var accelerationY = event.accelerationIncludingGravity.y;
var accelerationZ = event.accelerationIncludingGravity.z;
document.getElementById("varx").innerHTML = accelerationX;
document.getElementById("vary").innerHTML = accelerationY;
document.getElementById("varz").innerHTML = accelerationZ;
};
</script>
it will show this value only if the event have the accelerationIncludingGravity property, this is only available in mobile, not 100% this is what you want, you could also trigger an event asking for if(accelerationX){//execute action}else{//execute planB} hope this help, if it doesn't I'll be happy to learn and get some feedback.

Related

Detect if console/devtools is open in all browsers

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

Latest Desktop Firefox recognized as touch device?

has anyone noticed that on the last version of Desktop Firefox, it is recognized as a touch device?
I am using the script below:
function isTouch() {
try{ document.createEvent("TouchEvent"); return true; }
catch(e){ return false;
}
}
if (isTouch()) {
alert('I am touch device!')
}
The script has given me flawless results up until the latest version of Desktop Firefox. Is it a bug? Am I missing something?
Thanks everyone for your time!
edit: False alarm people. I have no idea what went wrong, I tried resetting preferences, disabled all extensions but had no luck.
I finally solved the issue by REFRESHING firefox (lost all my extensions though and had to reinstall).
Thanks for everybody's efforts and sorry for any inconvenience caused.
You are just checking if you can create a specific type of event, not really if you are currently on a touch device.
Here is a more complete isTouchDevice function, which I wrote some time ago based on the core of Modernizr.
/**
* Detect if the current device is a touch device.
* Inspired by Modernizr and hardcore streamlined.
*/
function isTouchDevice() {
var bool;
if( ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch ) {
bool = true;
}
else {
var fakeBody = document.createElement( 'fakebody' );
fakeBody.innerHTML += '<style>#media (touch-enabled),(-webkit-touch-enabled),(-moz-touch-enabled),(-o-touch-enabled){#touchtest{top:42px;position:absolute}}</style>';
document.documentElement.appendChild( fakeBody );
var touchTestNode = document.createElement( 'div' );
touchTestNode.id = 'touchtest';
fakeBody.appendChild( touchTestNode );
bool = touchTestNode.offsetTop === 42;
}
return bool;
}
I've had a similar problem, and maybe some people will benefit from the information.
In my case, the Touch events were always detected as positive by Modernizr in Firefox desktop, even if they weren't fired.
In the end, I realized that 'dom.w3c_touch_events.enabled' had a value of '1' even if I didn't set it myself.
It was actually switched on by the "Touch" button in Responsive Design View, but never switched back to '0' even after disabling the Touch events with the very same button.
So I've reported a bug to Mozilla : https://bugzilla.mozilla.org/show_bug.cgi?id=1188270
You will find a test case there.
Basically, the only solution I had to go back to normal is to change manually the value of 'dom.w3c_touch_events.enabled' to '0' in 'about:config'.
And I'm now aware that by enabling Touch events in the Responsive Design View, I will have to manually switch it back after.
Hope this can help some people !

Detect device type with UI Automation

I am using ui-screen-shooter, which makes use of the UI Automation JavaScript API to take screenshots of apps. My app has a slightly different structure on iPad and iPhone, so I need to detect the device type in my shoot_the_screen.js script and run different code. I would like something equivalent to [[UIDevice currentDevice] userInterfaceIdiom] that I can use in JavaScript. Here is the best I have come up with. It works, but do you know of a cleaner, less device-dependent way to get the same information?
var target = UIATarget.localTarget();
var width = target.rect().size.width;
if (width == 1024 || width == 768)
{
// iPad
}
else
{
// iPhone
}
You can call model() on the target to get the information you need. That's exactly what I'm doing in the ui-screen-shooter itself.
var modelName = UIATarget.localTarget().model();
// This prints "iPhone" or "iPad" for device. "iPhone Simulator" and "iPad Simulator" for sim.
UIALogger.logMessage(modelName);

How to identify buggy behavior in "input" event without browser detection?

I'll start with the question. When a specific browser has a buggy implementation of a feature and your javascript needs to know whether the current browser has that buggy implementation or not so it can use an alternate strategy, how do you figure out if the implementation is buggy without doing browser type sniffing (which is generally considered bad)?
Here's the whole situation.
I was working on some code that wants to use the "input" event for getting notifications of user changes to an <input type="text"> field (works much more live than the "change" event), but when that event isn't supported, it uses a much more complicated scheme involving a bunch of other events.
Since the "input" event is only supported in some browsers, I went in search of a way to do feature detection for the event (rather than browser user agent sniffing) since feature detection is generally a more robust way of doing things. As such, I came across this great article for doing exactly that and this code seems to work:
var isEventSupported = (function(){
var TAGNAMES = {
'select':'input','change':'input',
'submit':'form','reset':'form',
'error':'img','load':'img','abort':'img'
}
function isEventSupported(eventName) {
var el = document.createElement(TAGNAMES[eventName] || 'div');
eventName = 'on' + eventName;
var isSupported = (eventName in el);
if (!isSupported) {
el.setAttribute(eventName, 'return;');
isSupported = typeof el[eventName] == 'function';
}
el = null;
return isSupported;
}
return isEventSupported;
})();
Then, I ran into problems with IE (surprise, surprise). While IE purports to support the "input" event and it passes the feature test above and it works most of the time, IE's support is buggy as hell. It doesn't even trigger the event when the user hits the backspace key (among other missing behaviors). As such, I can't rely on it in IE. So, I had built this nice clean code that did a feature test for the "input" event and uses it's very clean implementation when present and when not present used this much uglier work-around involving monitoring eight other events. Now, it's busted in IE because the feature test for the "input" event passes so the code attempts to use it, but it's buggy as hell so it doesn't work.
Since these IE bugs show up on user actions, I can't think of any way to devise a javascript feature test to identify the buggy behavior. As such, my only current path is to resort to browser sniffing and refuse to rely on the "input" tag if the browser is IE.
Are there any options here for identifying the buggy behavior in the "input" event besides browser sniffing? If one had to do browser sniffing, is there a way to identify IE by behavior rather than a user agent string that can be freely spoofed and isn't guaranteed to be accurate?
jamie-pate suggest something like this:
var broken = false,
ta = angular.element('<textarea>').on('input', function(evt) {
broken = true;
});
ta.attr('placeholder', 'IESUCKS');
So you can check for "supports input event and is not 'broken'" in your code.
See https://github.com/angular/angular.js/issues/2614?source=c
If you are interested in a cross-browser "input change" event, here is my implementation:
function onInputChange(domInput, callback) {
if (domInput.addEventListener) {
domInput.addEventListener('input', callback, false); // Firefox, etc.
} else if (domInput.attachEvent) {
domInput.attachEvent('onpropertychange', callback); // IE
}
}
Usage example:
var leInput = document.getElementById('myInput');
var leCallback = function () {
// awesome stuff here
};
onInputChange(leInput, leCallback);
Works in all browsers, supports keyboard input and copy/paste.
However there is the exception of that cursed IE9, which didn't exist at the time I wrote the above code. Would Microsoft ever consider fixing their bug? :\

Bring spell check window to foreground with JavaScript/JScript in Windows 7

I have some JScript code (converted from some old VBScript) that starts like this:
var Word = new ActiveXObject("Word.Basic");
Word.FileNew(); // opens new Word document
Word.Insert(IncorrectText);
Word.ToolsSpelling(); // opens spell check behind IE
The idea is to utilize the MS Word spell check for browser use, and it works well in XP, but the spell check box opens in the background in Windows 7 / IE 8 (this question tells me that the problem started in Vista and is probably an OS issue, not a browser or Office issue).
So my question is, how can I bring this window to the foreground? One important note is that the last line, Word.ToolsSpelling();, locks up my script, so anything I do will need to be before that.
I've tried
var wshShell = new ActiveXObject("WScript.Shell");
wshShell.AppActivate("Document1 - Microsoft Word"); // or some other text
before the ToolsSpelling call, but this does not do anything (maybe because the Word document is not actually revealed at this point?). Of course, this will only work if no "Document1" is already opened, so this is a questionable thought to begin with.
Per this answer, I tried using window.blur(); in order to blur IE, but this will only work if the IE window is the only one opened. Maybe there's some way I can loop through all opened windows and apply this?
SetForegroundWindow looked promising, but I don't know how to use it in JSript.
Any ideas?
Note: Browser permissions will be completely open for this site.
Update: Turns out if you use Word.Application, the spell check comes up in front as it should. Only the Word.Basic method has this problem (I don't expect to know why this side of eternity):
var wordApp = new ActiveXObject("Word.Application");
wordApp.Documents.Add();
wordDoc = wordApp.ActiveDocument;
... // safety checks before insertion
wordSelection.TypeText(IncorrectText);
wordDoc.CheckSpelling();
wordApp.Visible = false; // CheckSpelling makes the document visible
You might be able to jigger the window state. When the window is maximized after having been minimized, Windows will stack that in front (zIndex to top).
Something like:
var WIN_MAX = 2;
var WIN_MIN = 1;
var Word = new ActiveXObject("Word.Application");
Word.Visible = true;
// minimize the app
Word.WindowState = WIN_MIN ;
// in 500ms, maximize
setTimeout(function () {
Word.WindowState = WIN_MAX;
}, 500);
The setTimeout call seeks to work around a timing issue; Windows will sometimes "get confused" when a programmatic minimize/maximize happens in immediate succession. You might have to extend that delay a little, test it repeatedly and see what kind of results you get.

Categories