Main BLOGGER
Google
WWW THIS BLOG
Monday, July 30, 2007
 
firefox DOM reference

http://developer.mozilla.org/en/docs/Gecko_DOM_Reference


 
a way to communicate with orphan pop-up window

http://www.1pixelout.net/2005/04/19/cross-window-javascript-communication/

 

 

Cross-window Javascript communication

This solution is now officially obsolete. A much nicer and simpler solution is available here.

This is a solution to a problem that I’ve come accross several times before but never really had a go at solving. This time, I just had to get it right or we would have had to use a nasty system of hidden frames. Yuk!

The problem

Right, so you have this page you want to open in a popup and you want to be able to call JS functions defined in the popup from the main window. Nothing revolutionary here. When you create a popup with the window.open method, you can specify a name for the new window object and use it to reference the popup from the main window.

// Create a new popup window
var popupWin = window.open( url, "popupWin" );
 
// To call functions defined in the popup:
popupWin.doSomething();

Now, when the user navigates to another page in the main window, the reference to the popup window object is lost and you cannot communicate with the popup anymore. This can be problematic if you need the popup to stay open. You can re-create the popup with the open method but this always reloads the page and when your popup is a music player, you get a very rubbish user experience indeed.

So, using the music player as an example, what we would need is a way to maintain a persistent link between the player and its opener so that the main window can call methods to control the player.

The solution

What we need to do is get the popup to broadcast its existence to the main window. Fortunately, the popup is not as forgetful as our main window and still has a reference to its creator: self.opener. We can get the popup to remind the opener at regular intervals with this code:

function notifyOpener() {
        if(self.opener || !self.opener.popupWin) self.opener.popupWin = self;
}
 
setInterval( notifyOpener, 200 );

This ensures that any page opened in the main window gets notified. The interval time should be short enough for the window to be notified before the user gets a chance to click any links. Now, the main window can call functions of the popup:

// Initialise popup pointer
var popupWin = null;
 
function doSomething() {
        if( popupWin && !popupWin.closed ) {
               popupWin.doSomething();
        }
}

Initialising the popupWin variable ensures that the script doesn’t break if the popup is closed. Before making the call to the popup, we can also check the closed property of the popup window. When true, this property indicates that the popup window was closed by the user (hardly rocket science, heh?).

So, if we combine the code above with the open routine we get this for the main window:

// Initialise popup pointer
var popupWin = null;
 
function openPopup() {
        var url = "the_url_to_your_popup.htm"
        if( !popupWin || popupWin.closed ) {
               popupWin = window.open( url, "popupWin" );
        } else popupWin.focus();
}
 
function doSomething() {
        if( popupWin && !popupWin.closed ) {
               // The popup is open so call it
               popupWin.doSomething();
        } else {
               // The popup is closed so open it
               openPopup();
        }
}

And in the popup:

function notifyOpener() {
        if(self.opener || !self.opener.popupWin) self.opener.popupWin = self;
}
 
setInterval( notifyOpener, 200 );
 
self.focus();
 
function doSomething() {
        alert("I'm doing something");
}

That’s it. Well, actually no, there is one more thing: the popup script will start throwing errors if the user closes the main window or navigates to a page on a different domain. To prevent any unnecessary errors, we add the following lines to the popup script:

function handleError() { return true; }
window.onerror = handleError;

Download an example

17 comments

  1. Tom Gilkison's gravatar#1: Tom Gilkison Says:
    October 8th, 2005 at 7:48 am

I just finished an article to go over a similar problem I faced in the creation of a Web application - http://tom.gilki.org/programming/javascript/Login/

Seems like we run into these issues quite a bit, but nobody takes the time to document the solutions! Thanks for the info.

  1. Jiten's gravatar#2: Jiten Says:
    November 11th, 2005 at 4:20 am

Nice idea. Thanks a bunch for posting this!

It works like a charm in IE but seems to be spluttering in Firefox. Still working on it but if you have feedback that would help, would appreciate it.

Thanks.

  1. Jiten's gravatar#3: Jiten Says:
    November 11th, 2005 at 5:13 am

Replace the following line in the sample code here:
setInterval( notifyOpener, 200 );
with
setInterval(”notifyOpener()”, 200);

This should do the trick in Firefox. :-)

  1. Martin's gravatar#4: Martin Says:
    November 11th, 2005 at 10:00 am

Jiten: this shouldn’t be a problem in Firefox. I have just tested the code again and it worked just fine in Firefox. setInterval( notifyOpener, 200 ) is perfectly valid syntax.

Which version are you using and on which platform?

  1. Jiten's gravatar#5: Jiten Says:
    November 11th, 2005 at 7:11 pm

Martin, you are right. I think the problem was caused by a bunch of JavaScript alerts that i had put in there, they seem to have caused some issue (could not figure out what exactly). Once I removed the alerts both the versions (the one I posted and your original ones worked fine) in Firefox.

The strange thing is the alerts did not cause a problem in IE though!

BTW I was testing this on a Windows XP Professional. Version is Firefox 1.5.

Thanks once again for this neat piece of code! :)

  1. mitmaur's gravatar#6: mitmaur Says:
    December 1st, 2005 at 6:41 am

I can’t wait to try this out. From the previous posts, it seems that it works fine. Ive racked my brain for days trying to think of a solution to this nagging problem. thanks for finding the solution!

  1. Will's gravatar#7: Will Says:
    February 19th, 2006 at 2:23 am

Nice one! :)

Thanks a lot,

Will

  1. Ellie's gravatar#8: Ellie Says:
    March 19th, 2006 at 11:37 pm

Try this change to doSomething() so it waits for the function to load in the new window before trying to call it. If the function hasn’t loaded it will try again in 500 clicks. Also added an extra call at the end so only this function needs to be called if the new window hasn’t been opened yet.

function doSomething() {
if( popupWin && !popupWin.closed ) {
// The popup is open so call it IF the function is loaded
if (popupWin.doSomething) {
popupWin.doSomething();
}
else {
setTimeout(’doSomething()’,500);
}

} else {
// The popup is closed so open it
openPopup();doSomething();
}
}

  1. Ben Nadel's gravatar#9: Ben Nadel Says:
    June 19th, 2006 at 6:03 pm

This is awesome… I have been dealing with this situation for a while trying to get a pop-up rich text editor to be “cached” in the back ground and focused when available, or openned when it doesn’t exist. I think this is awesome and will do the trick.

Thanks!

  1. mazben's gravatar#10: mazben Says:
    September 22nd, 2006 at 3:44 pm

thanks for this code. It’s a good synthesis, and helps me a lot.

  1. Deva's gravatar#11: Deva Says:
    October 24th, 2006 at 5:57 pm

I have a situation where I am invoking function_A using setInterval function after every 500ms. If while processing any error happens in the function_A, I am using onError to handle it. It normally returns true as you mentioned. But the setInterval function stops invoking function_A from that point onwards. Is there anything I can do to make it continue its work?

  1. Martin's gravatar#12: Martin Says:
    October 25th, 2006 at 9:43 am

Deva: The onError solution isn’t very good at all. You should look at using try/catch instead. I wrote this article a long time ago. My JavaScript skills have improved a lot since. Maybe I should think about writing a better solution one day.

  1. Rob's gravatar#13: Rob Says:
    December 12th, 2006 at 9:35 pm

Wouldn’t the following do the same?

In the opener:

function openPopup() {
popupWin = window.open( “”, “popupWin” );
if( !popupWin || popupWin.closed ) {
popupWin = window.open( “the_url_to_your_popup.htm”, “popupWin” );
} else popupWin.focus();
}

In the popup:
No need for notifier.

  1. Martin's gravatar#14: Martin Says:
    December 12th, 2006 at 9:57 pm

Rob: can your code handle getting back control over orphaned popups? My code deals with the case where you open a popup, navigate to a different page and need to regain control of the popup. With your code, the next page won’t have a reference to the popup so can’t control it.

  1. Rob's gravatar#15: Rob Says:
    December 12th, 2006 at 10:03 pm

Slight correction to my previous post… You should also check for the presence of doSomething in the popup window (or any other non-null defined variable) since the open method will always return a valid object.

I believe the following code in the opener will do the same without the need for the notifier in the popup window.

function openPopup() {
popupWin = window.open( “”, “popupWin” );
if( !popupWin || popupWin.closed || !openWin.doSomething ) {
popupWin = window.open( “the_url_to_your_popup.htm”, “popupWin” );
} else popupWin.focus();
}

  1. Rob's gravatar#16: Rob Says:
    December 12th, 2006 at 10:09 pm

Martin,

My understanding is that so long as the orphaned popup has a unique window name (window.name) it will be accessible with open(”", windowName);

I would be curious if you knew of a case where this may not work.

Regards,
-Rob

  1. MC's gravatar#17: MC Says:
    February 19th, 2007 at 11:41 am

I’ve had the following problem: users browsing through the website, watching some external player version of a thumbnail show which is present at a small scale in multple site pages. I wanted to detect surely whether this popup is open, on the body onload of each page of the website (without reopening it). It seems to me that the notifyOpener() function is the only way available . Thank you!


Wednesday, July 25, 2007
 
Another good RPM link
Quoted from
http://www.idevelopment.info/data/Unix/Linux/LINUX_RPMCommands.shtml

RPM Commands

by Jeff Hunter, Sr. Database Administrator

This document contains an overview of the principal RPM commands for installing, uninstalling, upgrading, querying, listing, and checking RPM packages on your Red Hat Linux system.


# rpm -ivh foo-2.0-4.i386.rpm
# rpm -i ftp://ftp.redhat.com/pub/redhat/RPMS/foo-1.0-1.i386.rpm
# rpm -i http://oss.oracle.com/projects/firewire/dist/files/kernel-2.4.20-18.10.1.i686.rpm
Used to install a RPM package. Note that RPM packages have file naming conventions like foo-2.0-4.i386.rpm, which include the package name (foo), version (2.0), release (4), and architecture (i386). Also notice that RPM understands FTP and HTTP protocols for installing and querying remote RPM files.


# rpm -e foo
To uninstall a RPM package. Note that we used the package name foo, not the name of the original package file foo-2.0-4.i386.rpm above.


# rpm -Uvh foo-1.0-2.i386.rpm
# rpm -Uvh ftp://ftp.redhat.com/pub/redhat/RPMS/foo-1.0-1.i386.rpm
# rpm -Uvh http://oss.oracle.com/projects/firewire/dist/files/kernel-2.4.20-18.10.1.i686.rpm
To upgrade a RPM package. Using this command, RPM automatically uninstall the old version of the foo package and install the new package. It is safe to always use rpm -Uvh to install and upgrade packages, since it works fine even when there are no previous versions of the package installed! Also notice that RPM understands FTP and HTTP protocols for upgrading from remote RPM files.


# rpm -qa
To query all installed packages. This command will print the names of all installed packages installed on your Linux system.


# rpm -q foo
To query a RPM package. This command will print the package name, version, and release number of the package foo only if it is installed. Use this command to verify that a package is or is not installed on your Linux system.


# rpm -qi foo
To display package information. This command display package information including the package name, version, and description of the installed program. Use this command to get detailed information about the installed package.


# rpm -ql foo
To list files in installed package. This command will list all of files in an installed RPM package. It works only when the package is already installed on your Linux system.


# rpm -qf /usr/bin/mysql
mysql-3.23.52-3
Which package owns a file? This command checks to determine which installed package a particular file belongs to.


# rpm -qpl kernel-2.4.20-18.10.1.i686.rpm
# rpm -qpl ftp://ftp.redhat.com/pub/redhat/RPMS/foo-1.0-1.i386.rpm
# rpm -qpl http://oss.oracle.com/projects/firewire/dist/files/kernel-2.4.20-18.10.1.i686.rpm
List files in RPM file. This command allows you to query a (possibly) uninstalled RPM file with the use of the the "-p" option. You can use the "-p" option to operate on an RPM file without actually installing anything. This command lists all files in an RPM file you have in the current directory. Also note that RPM can query remote files through the FTP and HTTP protocols.


# rpm --verify mysql
To verify an installed package. This command will list all files that do NOT pass the verify tests (done on size, MD5 signature, etc). Where a file does NOT pass, the output is listed using the following codes that signify what failed:
    S File size
M Mode (includes permissions and file type)
5 MD5 sum
L Symlink
D Device
U User
G Group
T Mtime
Take for example the following:
  # rpm --verify mysql
S.5....T c /etc/my.cnf
This example indicates that file /etc/my.cnf failed on:
  File size 
MD5 Sum
Modified Time
However, the "c" tells us this is a configuration file so that explains the changes. It should still be looked at to determine what the changes were.


# rpm --checksig foo
To check a RPM signature package. This command checks the PGP signature of specified package to ensure its integrity and origin. Always use this command first before installing a new RPM package on your system. Also, GnuPG or Pgp software must be already installed on your system before you can use this command.



--
Pop (Pu Liu)

 
RPM by example
Quoted and tested from
http://dirac.org/linux/rpm.html

also see http://www.dirac.org/linux/


1. rpm package name convention
wine-0.9.2-1rh9winehq.i386.rpm
^^^^^                                          Package name: wine
        ^^^^^                                  Version number: 0.9.2 (independent of vendor)
                ^^^^^^^^^^^^^                Release number: 1rh9winehq (this is vendor specific!!)
                                 ^^^^^          Architecture: i386 (this package works on any 80386 compatible system)

It's possible that architecture is "noarch" which means you can install it on a linux system running on PC, sparc, alpha, etc.

2. query installed rpm package
rpm -q package-name  (installed or not?)
rpm -ql package-name (what did it install?)

for example, wine-0.9.2-1rh9winehq.i386.rpm
you can run

[pliu@liu Downloads]$ rpm -q wine
wine-0.9.2-1rh9winehq

[pliu@liu Downloads]$ rpm -ql wine
/etc/rc.d/init.d/wine
/usr/bin/msiexec
/usr/bin/notepad
/usr/bin/progman
/usr/bin/regedit
/usr/bin/regsvr32
/usr/bin/uninstaller
/usr/bin/wcmd
/usr/bin/wine
...

3. un-installed RPM package
rpm -e package-name

4. install RPM package
rpm -i package.rpm (the whole file name)

5. verify RMP package wellness
rpm -V package-name
For example, rpm -V wine
If nothing appears, then wine package is fine.

6. upgrade by force
rpm -U -nodeps package.rpm

--
Pop (Pu Liu)

Friday, July 20, 2007
 
URL encoding rules

java.net
Class URLEncoder

java.lang.Object
|
+--java.net.URLEncoder

public class URLEncoder
extends Object

The class contains a utility method for converting a String into a MIME format called "x-www-form-urlencoded" format.

To convert a String, each character is examined in turn:

ASCII code table:

http://www.december.com/html/spec/ascii.html
--
Pop (Pu Liu)

Tuesday, July 17, 2007
 
a good post about JSON/XML debate
http://www.b-list.org/weblog/2006/12/21/i-cant-believe-its-not-xml

quoted from the above link:

1.The answer is that JSON works because most people don't really need all that overhead, and because it's often possible to do really interesting things with really simple formats.

2.But once you get past the egos and the attachments to this or that language or tool, the XML/s-expressions debate basically comes down to XML people saying, "OK, you've got s-expressions, and they're pretty cool and they solve your problems. But they don't solve my problems, so I need something else."

--
Pop (Pu Liu)

 
A good idea of using Accessibility API to orchestrate GUI applications

http://www.markgrechanik.com/Coins.html

See supporting techniques at

MSAA
http://msdn2.microsoft.com/en-us/library/ms788733.aspx

and  SUN ACCESS
http://www.sun.com/access/articles/index.html
--
Pop (Pu Liu)


Powered by Blogger

Google
WWW THIS BLOG