Monday, March 22, 2010
My IE trash talkin' days may have an end in sight!
But the last few posts on the IE Blog have made the future look a little brighter (if only people upgrade their IE, or Windows does a better job of upgrading it for them)
Finally SVG!, Yay!
CSS rounded borders, hip hip horray!!
canvas, :)
It's just sad that IE7/6 is still a major contenders, ugghhh.
Monday, October 19, 2009
IE8 Image is undefined part 2
While I was searching for information on this topic I stumbled across this entry on Microsofts forums. The fourth comment down, by the user 'Fattymelt', stated that he was able to resolve the issue by simply removing the call to 'focus' of the pop-up.
var pop = window.open(...);
pop.focus(); // removing this prevents the Image from being undefined
Wellll... It did prevent the issue, but it doesn't look like it's the 'focus' function that's causing it. 'blur' also caused the issue along with everything else I called from the 'window.open' object. Not just function calls either, a simple check against the 'closed' property also yielded the issue.
So, it looks there are two options to get around this issue..
1. Do the iframe hack from my previous post.
2. Don't make any calls to the 'window.open' object
As a side not I tried to post some of these results to the MS forums thread above, but everytime I click the reply link in the forum it takes me to my profile. I can't seem to post any replies to any threads... :(
Friday, October 16, 2009
IE8 Image is undefined
We use Omniture for site analytics and it was in their script that the issue was occuring. One problem we faced was the fact that their javascript is obfuscated so trying to read through their code was no fun. From what we could gather it looked as though they where using an 'Image' object with it's source set as a generated URL to report statistics.
After a bit of fiddler, javascript and code commenting we where able to narrow the issue down to this scenario
1. Within one window call 'window.open(...)' to open a new window
2. On the server, during the request for the new window, do a redirect to the same page
3. Once the page has loaded, after the redirect, you no longer have an 'Image' object
4. If you reload the page you now, magically, have an 'Image' object
(the redirect back to the same page was due to the original design of a few pages the application had. Basically a parameter is included in the query-string that notifies the server to reset a session variable, and the redirect goes back to the same page without the variable in the query-string)
According to some searching there are other scenarios where the 'Image' is undefined. Add-ons can cause this issue as well.
So.. What to do about this. Well like I stated in my previous post I tried to report the issue with MS, but unfortunately I could only post a comment on one of their forums. I also have an ASP.NET sample project that can consistently reproduce this issue, but I have nowhere to send it to. Maybe they don't like bug reports? I also couldn't find any useful information during my searching that could resolve this issue so it was down to some wonderful hacking...
My first attempt was to simply add this script to the top of our Omniture script
function Image() { }
Image.prototype = document.createElement('image')
That doesn't create exactly what you want though. But is interesting that you can get an instance of 'Image' by using the document.createElement('image').
For my next attempt I tried to see if I could get a reference from the parent window using
Image = window.parent.Image
But from the child window the parents Image was also null, even though it really wasn't when you actually tested it on the parent. Lovely I know.
But I was getting somewhere, since I didn't have what I wanted in the pop-up I was trying to get it from another window. So then the object/iframe tags came into mind. I wondered if the problem would still exist within an object/iframe tag within the broken page since it's DOM is different than the pop-ups.
I also found a post on Dean Edward's blog doing exactly what I needed so it saved me a bit of time/testing.
Sooooo here it is in all it's glory.
/*@cc_on
if (typeof Image == 'undefined') {
(function() {
function createImage() {
var iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
window.frames[window.frames.length - 1].document.write("<script>window.parent.Image = Image;<\/script>");
//don't uncomment the line below as it causes IE8 to throw-up
//document.body.removeChild(iframe);
}
var wl = window.onload;
window.onload = function() { createImage(); if(!(!(wl))) { wl() } };
})();
}
@*/
We wouldn't have to do the anonymous function and bind to the window.onload event, but in our case this was added to the top of our Omniture script file which is used as a script include at the top of our files (before the body tag) so the additional code was added so it would still work. Otherwise you could just add it to your page at the top/bottom wherever (as long as it's before any reference to 'Image')
What it does?
Basically we just create an iframe and add it to the DOM. Then we write the script string to the iframe which causes IE to execute it immediately. From within the iframe the 'Image' isn't broken/undefined so we set the parent's(broken window) Image to the iframes(working) Image. We ended up leaving the iframe in the page after the reference was set because IE would barf otherwise. This may be due to the reference on the parent no longer pointing to anything, but who knows. Oh yeah it's also wrapped in conditional compilation so that good browsers don't have to worry about anything.
Google likes IE8 more than Microsoft does?
Google reported 'about 67,700' results while Bing reported '1,620,000' results.
Doh!
Friday, October 09, 2009
(Simplified) Block/Closure Extension to C/Objective C/C++
My previous post from yesterday showed the new block/closure feature of the C language. I think I may have made the block syntax more complex looking than it needed to be by including the full interface/object code along with it. So today I'll strip off some of that unneeded code and do a comparison of just the basic syntax of C/ObjC's new block with that of C#'s anonymous method.
typedef void(^Block)(char*);
- C#
delegate void Block(string msg);
- (void) test: (Block)block {
block("msg");
}
- C#
protected void Test(Block block) {
block("msg");
}
int main( int argc, const char *argc[] ) {
MyClass *mc = [[MyClass alloc] init];
[mc test: ^(char *msg) { printf("%s"), msg } ];
}
- C#
static void main( string[] args ) {
MyClass mc = new MyClass();
mc.Test((string msg) => { Console.WriteLine(msg); } );
}
Blocks 1 and 2 only have minor differences between the languages.
Block 3 has the most difference between the languages due to the SmallTalk like message passing syntax of ObjC
[obj msg] vs that of c#'s obj.msg
Like blocks 1 and 2, block 3 shows only minor differences between the block syntax in either language.
^() { }
vs
() => { }
Chrome and the Mac
Many have been reporting, as of recent, about the increased stability and additional support for things such as Flash etc. I decided to give it a try today from within Snow Leopard. The download link can be found here.
(hehe I'm blogging this post from Chrome and inserting the previous link does not work from Bloggers editor).
Installing went without issues, and it loaded up no problem. I tried out a few sites and it seems to be working great thus far. I even went to ChromExperiments.com to push it a bit. I used the experiment called Voxel Spacing as that one was really slow in Safari a few months back. Chrome ran it much faster than I remember Safari being able to cope from before. I decided to try it again to see if Safari had improved at all. Coincidentally it had and both Chrome and Safari where running it at almost identical FPS, Chrome having an . Firefox couldn't be let off the hook here so it had to be tested as well. It was actually the slowest of the three.
Chrome 18 fps/average while moving
Safari 17-18 fps/average while moving
Firefox 11-12 fps/average while moving (another issue was that Firefox wouldn't allow me to hold down the arrow key, it had to be spammed to keep it moving)
Some other things I've noticed is that almost all of the AJAX for Blogger doesn't work, or has issues (the auto-save fails, and quite a few of the buttons for font, links, etc don't function correctly)
It seems to use a pretty consistent 100% cpu process at idle.
I had to copy/publish this post from another browser because Chrome didn't like the 'PUBLISH POST' button
I do like it so far though and I'm sure they'll get some of these issues resolved, it isn't even beta yet so it's working better than expected already. :)
Block/Closure Extension to C/Objective C/C++
I've been trying to force myself to get back into some Objective C/Cocoa development. I got a bit of an itch again after looking into the new OpenCL. If you don't want to read all about it it's basically a standard that Apple started and was able to get Intel, Nvidia and AMD on board and eventually submitted it to the Krhonos group for standardization. It basically allows you to write programs to take advantage of all the cores of cpus/gpus, similiar in what Nvidia was doing with Cuda. To ease development when working with OpenCL blocks/closures where also added as an addition to C.
I really wanted to play around with some of these but was hard pressed to find any good examples for both C and ObjC.
So here's a quick one in plain ol' C
void test1( void(^block)(char*) ) {
block("Message from 'block'");
}
int main( int argc, const char *argv[] ) {
test1(^(char *msg) { printf("Block Message: %s\n", msg); });
return 0;
}
And in ObjC
- interface
#import <objc/Object.h>
typedef void(^Block)(char*);
@interface HelloWorld : Object {
}
- (void) displayBlockMessage: (Block)block;
@end
- implementation
#import "HelloWorld.h" @implementation HelloWorld - (void) displayBlockMessage: (Block)block { block("<HelloWorld> block message"); } @end
- main
#import "HelloWorld.h" int main( int argc, const char *argv[] ) { HelloWorld *helloWorld = [[HelloWorld alloc] init]; // inline block [helloWorld displayBlockMessage: ^(char *msg) { printf("%s\n", msg); }]; // declared block Block block = ^(char *msg) { printf("-=%s=-", msg); }; [helloWorld displayBlockMessage: block]; return 0; }
One thing you'll notice is that the interface declares 'block (typedef void(^Block)(char *);' This is because you need a type for the 'displayBlockMessage' functions signature (unless there's some trick :) ). Another thing is that I'm inheriting from the base objc object type and not the Cocoa NSObject, it will work either way I was just playing around with also compiling it on Windows.
I'm still surprised that C is getting block/closures before Java. C++0x is also suppose to have their own implementation as well.
TextMate Snow Leopard and
If you don't install it by using GIT, as the instructions say, you can simply download it from the above site and once un-tar'd change the name of the folder (something like 'drnic-copy-as-rtf-tmbundle-e490dbf') to 'Copy as RTF.tmbundle'. Then copy this to ~/Library/Application\ Support/TextMate/Bundles. If the bundles directory is not there then simply create it and then copy.
If TextMate is already running then click 'Bundles -> Bundle Editor -> Reload Bundles' to reload the bundles. It should work from here. I had an issue where it wasn't doing anything. I was able to track down the issue by altering the output of the bundle to get the exception. I'm by no means a TextMate expert I just happened to stumble across this. I went to 'Bundles -> Bundle Editor -> Show Bundle Editor' expanded the 'Copy as RTF' and selected the node. Then on the right pane changed the 'Output' drop-down from 'Discard' to 'Show as HTML'.
I was getting a Ruby deprecation warning and an exception about a corrupt theme. I didn't have any themes installed though. I looked through the Ruby code for the plugin where that error message was and found that it was looping through my non-existent 'Themes' folder. I downloaded a random theme and installed it and after that the exception went away and I can now get RTF output for any language in TextMate.
Thursday, October 08, 2009
Syntax Highlighting in Your Blog
Well... Apple removed that feature from Pages and I was stuck looking for other options. I was searching tonight and noticed a few people using the demo of GeSHi and editing the resulting page source etc. That was a bit more work than I was willing to do.
I remembered a while back that Google Docs would also preserve RTF when pasting. So I embarked on a test. I copied some source code from XCode and pasted it into Google Docs. Then I did a quick look at the DOM and found exactly the piece I wanted. I then added this bit in the URL(as one line)
javascript:alert(document.getElementById('wys_frame')
.contentDocument.getElementsByTagName('body')[0].innerHTML)
And copied the result from the pop-up and pasted it into my blog. The only caveat is the editor you're copying from needs to copy your snippet as RTF
(I used this to generate the above javascript)
Friday, October 02, 2009
Snow Leopard Python 32-bit Script
One that has mattered for me however is Python. Snow Leopard comes with Python 2.6 instead of 2.5 which it's predecessor included. The 2.6 that's included in SL also defaults to 64 bit. Although this is 'geeky' cool it has caused quite a few problems with other python applications/libraries. I'm sure this will change in the future but for now it's not so much fun.
A quick fix that quite a few people have done is doing either from the terminal
defaults write com.apple.versioner.python Prefer-32-Bit -bool yes
or
export VERSIONER_PYTHON_PREFER_32_BIT=yes
With the first it's a permanent change, unless you re-execute it with 'no' in place of 'yes'.
The second is per session.
I didn't like the idea of making it permanent, and switching it all the time so I created a quick script.
#! bin/sh
PY_ARG="$1"
export VERSIONER_PYTHON_PREFER_32_BIT=yes
python $PY_ARG
I also created the directory /usr/local/bin, as this isn't created in the default SL install but it is included in the default .bash_profile path variable so you don't have to update your path.
(I saved mine as python32.sh)
Then do a quick chmod to add the executable bits (sudo chmod 755 python32.sh or sudo chmod u+x python32.sh)
Now I can simply type in 'python32.sh' and I've got Python 2.6 in 32-bits. Or if I wanted to run a python app/script in 32-bit I could type in 'python32.sh myscript.py'
Happy scripting!!
Taskbar At The Top Is Naughty
Awright, I right click on the app in the taskbar expecting the 'move' option that's in XP. Ummm.. it's gone.. Awright lets move my taskbar back to the bottom of the screen and then move the window and then move the taskbar back to the top. I got inconsistent results with this step. Sometimes when I moved the taskbar back to the top it would be a pal and move the application back under the taskbar and sometimes it would leave it where it was after I moved it.
It would consistently open the dev tools under the task bar if IE was loaded to a full screen.
I love features! They give me something to do when I'm bored
Windows 7, .NET and IPv6
We have an application that does some impersonation if you are within our firewall and part of the same non-routable subnet blah blah... I noticed that from within my Windows 7 VM I could not hit a portion of our application. A nice little exception was occurring. From outside my VM I didn't have any issues.
After a quick look it was due to local connections to IIS defaulting to an IPv6 address, no 'localhost'. So I navigated through the windows to get to the network card settings and disabled the IPv6 protocol for the card. 'That should do it' I thought. Nope! It still used the IPv6 for loopback.
Awright Google, lead me towards the light. This post started out the same way. Disabling the IPv6 for the card, but towards the bottom there's a lovely registry, cringe, modification. Basically it's in 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters. Add a 32-bit DWORD item with the name of 'DisabledComponents' and a value of '1'. You also have to reboot :(
'Awright, now I'm good'.... WRONG! Now it was using '::1' for the loopback. Awright, lets see what's in the 'hosts' file. Go to 'C:\Windows\System32\drivers\etc' and open the 'hosts' file. And we find out that we can't simply edit it. Just like my previous .sln post you have to first load notepad, or whatever, as admin and then open the file. You'll have to re-navigate to the file since you also can't simply drag and drop the file onto your open session of notepad. Extra steps build character :)
Comment out the entry
127.0.0.1 .host
with a '#'
Yay! now it finally works like it used to....
Monday, September 21, 2009
Snow Leopard 64 bit kernel on a MacBook5,1
I was playing around with Snow Leopard today and for no better reason than "It's neat" I decided to try and boot into the 64 bit kernel. Apple has left the default kernel, on non server editions, to default to 32 bit. Many people have complained about this stating it's slower and can't access > 4GB of memory and can't run 64 bit apps correctly etc etc. Well it's all a little bit of FUD. Apple also included the 64 bit kernel ability but defaulted it to 32 mainly to avoid 3rd party software/drivers/kexts that rely on the 32 bit kernel. Windows Vista 64 had similar issues with drivers etc. And while in 32 bit kernel mode applications can still run in 64 bit mode just fine, without any type of 64 to 32 virtualization. So right now there really is no reason, for most, to run in 64 kernel mode other than "It's neat".
If you'd like to try, and have a 64 bit cpu with 64 bit EFI (Core 2 duo / Xeon), simply reboot/turn-on and hold down the '6' and '4' keys. If it works your computer will boot a little bit slower as it makes the switch (if you set it to always boot in 64 bit mode you wont see this delay). You can check wether it worked or not by either checking the kernel process in the Activity Monitor or type
uname -a
in the terminal. The result will end in 'x86_64' if it worked. Or you can also click the 'Apple' and go to 'About This Mac' and click the 'More Info...' button. From there click the 'Software' group towards the bottom. The line that says '64-bit Kernel and Extensions' should say 'Yes'.
If it didn't work then you may be lucky like me and have a MacBook or Air etc. Apple has black-listed these and deemed it an option only available for the elite Pros (MacBook Pros, MacPros...and XServes). But you can still try it thanks to this guy, Amit Singh. It's been a while since I've had to use a hex-editor for something like this but it was fun :)
0xED, and Hex Fiend are both good...
Basically I followed his post pretty close. Simply made a copy of /usr/standalone/i386/boot.efi (I called it boot64.egi) as /System/Library/CoreServices/boot64.efi
Then opened it with a hex editor and adjusted the 'black-flag' bit value for my corresponding machine.
(I didn't have to chown the file or chflags as my copy was already set)
Then blessed it with
sudo bless --folder /System/Library/CoreServices --file /System/Library/CoreServices/boot64.efi
This sets the newly modified .efi to be used during boot.
After that you can now use the '6' + '4' and the '3' + '2' options while booting/restarting.
I also set mine to always load using the 64 bit kernel, again for no better reason than "it's neat-o". This can be done by editing the file
/Library/Preferences/SystemConfiguration/com.apple.Boot.plist
And change this
<key>Kernel Flags</key>
<string></string>
to this
<key>Kernel Flags</key>
<string>arch=x86_64</string>
Now Snow Leopard will boot by default with the 64 bit kernel, you can still hold down the '3' + '2' to boot using the 32 bit kernel.
Problems:
I'm running on a pretty fresh install of Snow Leopard and haven't done a whole lot of testing yet. But so far most things run great. 32 bit applications still function fine in their 32 bit modes as well. The only application that hasn't worked so far is VMWare Fusion, but this may change with the next version or so. VirtualBox does indeed work with the 64 bit kernel though so I will be trying that out with Windows 7 in the next few days.