31 July 2014

Internet Explorer Woes Still!

Microsoft WHY WHY WHY!


I have gone back in time.   I am fighting with IE AGAIN.

Internet Explorer Version 11.  Its the latest and greatest, and for the most part standards compliant browser.  Well done.

SVG


Today I have been using SVG graphics.  SVG's are awesome, they are the future, they should have been around 10 years ago, except for IE's failure to support them.  Finally now all modern browsers support them (and have done for a while), at least in their basic incarnation.

<img src="mywonderfulgraphic.svg" />

Ok, I still have to have image fallback for IE8 and below, and older androids.

<img onerror="this.onerror=null;this.src='fallback.png'" src="newshiny.svg" />

There are other ways to do this I agree, but this way to me seems the simplest, and most efficient.

I have also added a simple server optimisation.  Doing some "evil" browser sniffing, if the browser is MSIE 8 or below, I just serve the PNG, and don't bother with SVG. 

<img src="fallback.png" />

So far so good.

Until we come to IE11


IE has an SVG scaling bug, which means the SVG image wont scale correctly: Given a percentage width it wont scale the height appropriately resulting in stretched images. PNG's scale just fine.

I investigated trying to fiddle it, using CSS, but without jumping through a lot of hoops, it becomes just awkward.  So my next thought was, it's ok, I can just deliver the PNG instead, I'll just use the browser sniffing to check the IE version.

The IE team have decided to the remove "MSIE" from the User Agent String.  I now dont know which browser is talking to the server, because IE pretends to be all of them.

(Update) Actually they have changed the User Agent String, and after a bit of fidding the IE browser version can be detected for any IE version using the following regex:

\b(?:MSIE\s|Trident\/[0-9.]+;\srv:)([0-9.]+)

It can used like this from PHP: 

$version = [false,false];
$isIE = preg_match("/\b(?:MSIE\s|Trident\/[0-9.]+;\srv:)([0-9.]+)/",$_SERVER['HTTP_USER_AGENT'],$version);
return $isIE? $version[1]: false; 

Aha!, they say "You should be using feature detection instead of User Agent sniffing".

Well thats all very well if your features worked like they should, then I wouldn't have to deliver browser specific content in the first place.  Which, as a matter of fact, is why browser sniffing was needed in the first place!

What about conditional comments you say. 

Nope they don't work for IE11 either. The IE team decided to remove them from IE 11. 

Rock meet Hard Place.


(Update) There are various sites on the interwebs which give ideas about getting round the SVG issue eg. larrybotha on github

If I make sure the SVG has the viewBox attribute set, I can set the height in CSS to 100%

To target IE 10+ browsers, use the following css media query:

@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
    /* IE10+ specific styles */
    .selector img[src$=".svg"] { height: 100%; }
}

I got that hack from here: limecanvas.com


(Update) Safari also suffers from SVG scaling bugs.  I was trying to do hovering on scaled images, using image replacement, and every time the image got swapped, it messed up the image aspect or scaling.



22 July 2014

Pasting into a photoshop channel/layer/alpha mask

All I want to do is paste into the channel mask of a layer, this is where GIMP has a big win.  Right click, then select create greyscale copy of layer as mask.  Yay, exactly what I want to do.

Photoshop has an all or nothing approach, reveal all or reveal none, to create an all black or all white mask, I then have to paste to the mask, but to paste to the mask I have to enable/make it visible first.

The easiest way:

Alt-Click the layer mask. (To enable direct editing of the layer mask)
Ctrl-V to paste into the layer mask.

The slightly more convoluted way:

Click on the channels list, then click on the eye next to mask layer to make it visible/editable.
Ctrl-V to paste into the layer mask.

Further, if you want to automate the paste into mask, you need to use Ctrl-Shift-V.

23 June 2014

Netsupport Mac Client CPU Issue

Netsupport is great.  It allows you to remote access, and control other machines on your network.  Of course there are other ways to do it eg RDP, and VNC, but netsupport nicely ties it all together and makes it very easy.

I did have an issue however, on the Mac, I just wanted to install the Netsupport Manager,  ie I just wanted to control other machines, and not be controlled.  During the installation there didn't seem to be any options to not install the client, but as I checked the 'control and manage only' option (or words to that effect) and assumed the client wouldn't be installed.  

Not only was the client installed, but when the machine is idle. The Netsupport Client processing is running, and taking up about 8-10% CPU all the time.  As I have a reasonably decent machine (OS X 10.9.3, 2.3GHz i7, 16GB RAM) this CPU use is hardly noticeable, but it really bugged me.

Killing the process wont work as it's restarted automatically, so I had to look a little deeper.

The secret is in

/Library/Preferences/NetSupport/NetSupportManager

There are 2 files:

ns-login.sh
ns-logout.sh

In the login file I just commented out the line where the monitoring process is started:

#${SESSIOND} "*" /s &

This stops the client from being started, and restarted.  The Netsupport Manger still works, ie connects and Controls other machines, but I dont have the Client eating 10% of my CPU now.

16 April 2014

MySQL Disable Foreign Key Checks

What and Why


Here are some test results regarding foreign key checks in mysql, and what actually happens to the data, when you change the relation type, eg CASCADE, SET NULL, RESTRICT, and NO ACTION.


I basically want to check whether foreign keys are processed on the table after the key checks are reenabled, or they are ignored completely, or if there is some other vooodoo that happens.

Method


I setup 2 Tables, T1 and T2, T1 has a primary key (id) and T2 has a foreign key (ref) which points to T1.id.

For the test I just did updates to the id in T1, and deleted a row in T1, and watched what happened to the data in T2, for each of the FK relations types.

The code used to disable the foreign key checks is:

SET foreign_key_checks = 0;
-- UPDATE `test1` set id=13 where id = 3;
DELETE FROM `test1` WHERE id = 3;
SET foreign_key_checks = 1;

I commented out the delete or update line as appropriate.
and then reset the tables after each test.



Results


Normal Operation
================
CASCADE on update = both records updated
CASCADE on delete = both records deleted
SET NULL on delete = row deleted and ref set to null
SET NULL on update = row updated and ref set to null
RESTRICT on delete = delete prevented
RESTRICT on update = update prevented
NO ACTION on update = update prevented
NO ACTION on delete = delete prevented

Disable FK Checks
=================
CASCADE on update = row updated and leaves dangling ref
CASCADE on delete = row deleted and leaves dangling ref
SET NULL on update = row updated and leaves dangling ref
SET NULL on delete = row deleted and leaves dangling ref
RESTRICT on update = row updated and leaves dangling ref
RESTRICT on delete = row deleted and leaves dangling ref
NO ACTION on update = row updated and leaves dangling ref
NO ACTION on delete = row deleted and leaves dangling ref

Conclusion


The most obvious conclusion, is that disabling foreign key checks as a  part of the update or delete process can leave invalid foreign keys in the database.  While there might be good reasons for doing this, the chance that the data will be left in an inconsistent state is very high.