Stylesheet switcher in Safari 5.1 WebKit 534 - javascript

I have a stylesheet switcher which works fine in all mainstream browsers until Safari 5.1 and possibly a past version of Chrome. The source of the problem appears to be in WebKit version 534. Other designers have experienced similar problems:
https://discussions.apple.com/thread/3215084?start=0&tstart=0
This version of WebKit appears not to action:
a.disabled = false
in the following script:
function changeLayout(description){
var i, a;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++){
if(a.getAttribute("title") == description){a.disabled = false;}
else if(a.getAttribute("title") != "default"){a.disabled = true;}
}
}
(or perhaps it may be the case that it will only allow one active stylesheet, the default?)
I have alternative code I can deliver to switch the stylesheet but it is more onerous and I only want to run it if the usual method would fail.
Is there a way I could test if the browser is respecting
"a.disabled = false" (or true for that matter)
and then deliver the alternative code if not?
OR is there a reliable way to test for WebKit version 534?

I know jQuery.Browser can detect things like webkit and versions. Check it out here:
http://api.jquery.com/jQuery.browser/
Edit
Looks like it is now depricated, replaced with jQuery.Support:
http://api.jquery.com/jQuery.support/

Related

Safari ignores window.matchMedia

I'm using window.matchMedia conditional in order to avoid the inject of a video in mobile devices. CanIUse reports that matchMedia is going to work smoothly since Safari 9 (I'm testing on it), but my code is completely ignored:
if ( window.matchMedia("(min-width: 1025px").matches) {
console.log('match');
document.addEventListener("DOMContentLoaded", function() { initialiseMediaPlayer(); }, false);
function initialiseMediaPlayer() {
(stuff here...)
}
}
This code works perfectly on Chrome, Chromium, Firefox, IE and Edge.
Does anyone had a similar issue?
The issue is in the formatting, oddly enough the other browsers fix the behavior even though it is malformed. It's missing an additional closing ")" parenthesis after the 1025px. Try:
if ( window.matchMedia('(min-width:1025px)').matches) {
console.log('match');
document.addEventListener("DOMContentLoaded", function() { initialiseMediaPlayer(); }, false);
function initialiseMediaPlayer() {
(stuff here...)
}
}
For anyone else who may come across similar issues, I found that in safari you need to include 'screen and' as well as the width setting. Other browsers seem to assume that you are talking about the screen width but safari needs it specified, at least in my case. so would be something like:
if ( window.matchMedia('screen and (min-width:1025px)').matches) {}
in this case
In my case, it was that Safari uses .addListener() instead of addEventListener() on the mediaQueryList.
If someone stumbles across this too, in my case the problem was, that safari doesn't have the .onchange property on the MediaQueryList interface.
This was just resolved in Safari 14, but the release is rather new, so use (the deprecated) .addListener if you want to ensure backwards compatibility.
Source: https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/onchange

How can I detect CSS Variable support with JavaScript?

The latest version of Firefox has support for CSS Variables, but Chrome, IE and loads of other browsers do not. It should be possible to access a DOM Node or write a little method which returns whether the browser supports this feature, but I haven't been able to find anything which is currently able to do this. What I need is a solution which I can use as condition to run code if the browser does not support the feature, something like:
if (!browserCanUseCssVariables()) {
// Do stuff...
}
We can do this with CSS.supports. This is the JavaScript implementation of CSS's #supports rule which is currently available in Firefox, Chrome, Opera and Android Browser (see Can I Use...).
The CSS.supports() static methods returns a Boolean value indicating if the browser supports a given CSS feature, or not.– Mozilla Developer Network
With this, we can simply:
CSS.supports('color', 'var(--fake-var)');
The result of this will be true if the browser supports CSS variables, and false if it doesn't.
(You might think that CSS.supports('--fake-var', 0) would work, but as noted in comments on this answer Safari seems to have a bug there making it fail.)
Pure JavaScript Example
On Firefox this code snippet will produce a green background, as our CSS.supports call above returns true. In browsers which do not support CSS variables the background will be red.
var body = document.getElementsByTagName('body')[0];
if (window.CSS && CSS.supports('color', 'var(--fake-var)')) {
body.style.background = 'green';
} else {
body.style.background = 'red';
}
Note that here I've also added checks to see whether window.CSS exists - this will prevent errors being thrown in browsers which do not support this JavaScript implementation and treat that as false as well. (CSS.supports was introduced at the same time CSS global was introduced, so there's no need to check for it as well.)
Creating the browserCanUseCssVariables() function
In your case, we can create the browserCanUseCssVariables() function by simply performing the same logic. This below snippet will alert either true or false depending on the support.
function browserCanUseCssVariables() {
return window.CSS && CSS.supports('color', 'var(--fake-var)');
}
if (browserCanUseCssVariables()) {
alert('Your browser supports CSS Variables!');
} else {
alert('Your browser does not support CSS Variables and/or CSS.supports. :-(');
}
The Results (all tested on Windows only)
Firefox v31
Chrome v38
Internet Explorer 11
Set a CSS style with CSS variables and proof with Javascript and getComputedStyle() if it is set...
getComputedStyle() is supported in many browsers: http://caniuse.com/#feat=getcomputedstyle
HTML
<div class="css-variable-test"></div>
CSS
:root {
--main-bg-color: rgb(1, 2, 3); /* or something else */
}
.css-variable-test {
display: none;
background-color: var(--main-bg-color);
}
JavaScript
var computedStyle = getComputedStyle(document.getElementsByClassName('css-variable-test')[0], null);
if (computedStyle.backgroundColor == "rgb(1, 2, 3)") { // or something else
alert('CSS variables support');
}
FIDDLE: http://jsfiddle.net/g0naedLh/6/
You don’t need Javascript to detect if a browser supports custom properties, unless the Do stuff... is Javascript itself. Since the thing you’re detecting support for is CSS, I assume that the stuff you’re trying to do is all CSS. Therefore, if there’s a way to remove JS from this specific problem, I would recommend Feature Queries.
#supports (display: var(--prop)) {
h1 { font-weight: normal; }
/* all the css, even without var() */
}
Feature queries test support for syntax. You don’t have to query for display; you could use any property you want. Likewise, the value of --prop need not even exist. All you’re doing is checking to see if the browser knows how to read that syntax.
(I just chose display because almost every browser supports it. If you use flex-wrap or something, you won’t catch the browsers that do support custom props but that don’t support flexbox.)
Sidenote: I prefer calling them Custom Properties because that is exactly what they are: properties defined by the author. Yes, you can use them as variables, but there are certain advantages to them as properties, such as DOM inheritance:
body { --color-heading: green; }
article { --color-heading: blue; }
h1 { color: var(--color-heading); } /* no need for descendant selectors */
I had problems getting the window.CSS.supports method to work for testing css variables in chrome 49 (even though it has native support). Ended up doing this:
var supportsCssVars = function() {
var s = document.createElement('style'),
support;
s.innerHTML = ":root { --tmp-var: bold; }";
document.head.appendChild(s);
support = !!(window.CSS && window.CSS.supports && window.CSS.supports('font-weight', 'var(--tmp-var)'));
s.parentNode.removeChild(s);
return support;
}
console.log("Supports css variables:", supportsCssVars());
Seems to work in all browsers I tested.
Probably the code can be optimised though.

programmatic way to check which version is installed?

Is there a way through javascript to see what version (or rollup) the crm organization/server is on? What I really want to know is if I am on UR11 or before.
I've tried:
Xrm.Page.context - but nothing about versions (did I miss something?)
Checking if (crmForm == null) (Since that was disabled as of UR12) The problem is that if the org enables HTC support then crmForm will not be null, and I need to know what version with or without HTC support enabled.
What I've done for now is put the onus on the solution installer to modify a javascript file that has the "isRollup12" variable to true or false, which is quite clunky.
There is a global JS variable you could check:
alert(APPLICATION_FULL_VERSION);
//on UR12 '5.0.9690.3236'
//on UR11 '5.0.9690.2839'
//and so on...
But this method isn't supported, so use at your own risk.
you can check if the getClientUrl function is defined, it's a new function included inside UR12.
var isRollup12 = false;
if (Xrm.Page.context.getClientUrl !== undefined) {
isRollup12 = true;
}

Browser Issue: Charts are not rendered on IE8

We have inhouse library which uses canvas for displaying charts in my application. And dojo as scripting language.Everything is fine, but my charts are not appearing in IE8.
I google about this, and found that there is some VML issue in IE8.
I found this:
var printChart = function(time, freq){
if (!document.namespaces['g_vml_']) {
document.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml', '#default#VML');
}
if (!document.namespaces['g_o_']) {
document.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office', '#default#VML');
}
if (freq === undefined) {
this.freq = "1mi";
}
if (time === undefined) {
this.time = "1dy";
}
self.reload();
}
Now I was trying to add this in my DOJO code and that is creating problem.
As when I do document.namespace I get firebug error 'document.namespaces is undefined'.
Q: How can we fix this, are the any better alternative approaches for the same, basic problem am having is browser related, charts are rendered properly on other browsers but not on IE8, any suggestions ?
Update:
What are ways to deal with such cross browser issue ?
Regarding the cross-browser issues you mentioned, there are basically two ways: browser sniffing and object detection. Browser sniffing is to detect the browser vendor and version. For example, you can know that the browser is IE 8 or Firefox 4.0 from the navigator object. Object detection is to test whether a object/function is available on the browser before actually using it.
For the problem you have here, you can use the two approaches. For example, you can sniff the browser using dojo.isIE.
if (dojo.isIE == 8) {
//Your code to add the namespace
}
Or you can use:
if (document.namespaces) {
// Your code to add the namespace
}

The best way of checking for -moz-border-radius support

I wanted some of those spiffy rounded corners for a web project that I'm currently working on.
I thought I'd try to accomplish it using javascript and not CSS in an effort to keep the requests for image files to a minimum (yes, I know that it's possible to combine all required rounded corner shapes into one image) and I also wanted to be able to change the background color pretty much on the fly.
I already utilize jQuery so I looked at the excellent rounded corners plugin and it worked like a charm in every browser I tried. Being a developer however I noticed the opportunity to make it a bit more efficient. The script already includes code for detecting if the current browser supports webkit rounded corners (safari based browsers). If so it uses raw CSS instead of creating layers of divs.
I thought that it would be awesome if the same kind of check could be performed to see if the browser supports the Gecko-specific -moz-border-radius-* properties and if so utilize them.
The check for webkit support looks like this:
var webkitAvailable = false;
try {
webkitAvailable = (document.defaultView.getComputedStyle(this[0], null)['-webkit-border-radius'] != undefined);
}
catch(err) {}
That, however, did not work for -moz-border-radius so I started checking for alternatives.
My fallback solution is of course to use browser detection but that's far from recommended practice ofcourse.
My best solution yet is as follows.
var mozborderAvailable = false;
try {
var o = jQuery('<div>').css('-moz-border-radius', '1px');
mozborderAvailable = $(o).css('-moz-border-radius-topleft') == '1px';
o = null;
} catch(err) {}
It's based on the theory that Gecko "expands" the composite -moz-border-radius to the four sub-properties
-moz-border-radius-topleft
-moz-border-radius-topright
-moz-border-radius-bottomleft
-moz-border-radius-bottomright
Is there any javascript/CSS guru out there that have a better solution?
(The feature request for this page is at http://plugins.jquery.com/node/3619)
How about this?
var mozborderAvailable = false;
try {
if (typeof(document.body.style.MozBorderRadius) !== "undefined") {
mozborderAvailable = true;
}
} catch(err) {}
I tested it in Firefox 3 (true) and false in: Safari, IE7, and Opera.
(Edit: better undefined test)
I know this is an older question, but it shows up high in searches for testing border-radius support so I thought I'd throw this nugget in here.
Rob Glazebrook has a little snippet that extends the support object of jQuery to do a nice quick check for border-radius support (also moz and web-kit).
jQuery(function() {
jQuery.support.borderRadius = false;
jQuery.each(['BorderRadius','MozBorderRadius','WebkitBorderRadius','OBorderRadius','KhtmlBorderRadius'], function() {
if(document.body.style[this] !== undefined) jQuery.support.borderRadius = true;
return (!jQuery.support.borderRadius);
}); });
Attribution
That way, if there isn't support for it you can fall back and use jQuery to implement a 2-way slider so that other browsers still have a similar visual experience.
Why not use -moz-border-radius and -webkit-border-radius in the stylesheet? It's valid CSS and throwing an otherwise unused attribute would hurt less than having javascript do the legwork of figuring out if it should apply it or not.
Then, in the javascript you'd just check if the browser is IE (or Opera?) - if it is, it'll ignore the proprietary tags, and your javascript could do it's thing.
Maybe I'm missing something here...
Apply CSS unconditionally and check element.style.MozBorderRadius in the script?
As you're already using jQuery you could use jQuery.browser utility to do some browser sniffing and then target your CSS / JavaScript accordingly.
The problem with this is that Firefox 2 does not use anti-aliasing for the borders. The script would need to detect for Firefox 3 before is uses native rounded corners as FF3 does use anti-aliasing.
I've developed the following method for detecting whether the browser supports rounded borders or not. I have yet to test it on IE (am on a Linux machine), but it works correctly in Webkit and Gecko browsers (i.e. Safari/Chrome and Firefox) as well as in Opera:
function checkBorders() {
var div = document.createElement('div');
div.setAttribute('style', '-moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px;');
for ( stylenr=0; stylenr<div.style.length; stylenr++ ) {
if ( /border.*?-radius/i.test(div.style[stylenr]) ) {
return true;
};
return false;
};
If you wanted to test for Firefox 2 or 3, you should check for the Gecko rendering engine, not the actual browser. I can't find the precise release date for Gecko 1.9 (which is the version that supports anti-aliased rounded corners), but the Mozilla wiki says it was released in the first quarter of 2007, so we'll assume May just to be sure.
if ( /Gecko\/\d*/.test(navigator.userAgent) && parseInt(navigator.userAgent.match(/Gecko\/\d*/)[0].split('/')[1]) > 20070501 )
All in all, the combined function is this:
function checkBorders() {
if ( /Gecko\/\d*/.test(navigator.userAgent) && parseInt(navigator.userAgent.match(/Gecko\/\d*/)[0].split('/')[1]) > 20070501 ) {
return true;
} else {
var div = document.createElement('div');
div.setAttribute('style', '-moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px;');
for ( stylenr=0; stylenr<div.style.length; stylenr++ ) {
if ( /border.*?-radius/i.test(div.style[stylenr]) ) {
return true;
};
return false;
};
};

Categories

Resources