Once we have the plug-ins or ActiveX controls embedded into the page, their actual use is very similar. To make life easier for us, most developers of plug-ins and controls make the properties, methods, and events supported by the plug-in and ActiveX control similar. However, it's important to check the developer's documentation because it's likely that there will be some differences.
Inside the <embed> or <object> tag, we give our plug-in or control a unique id value. We can then access the corresponding object's methods, properties, and events just as we would for any other tag. The actual properties, methods, and events supported by a plug-in or control will be specific to that control, but let's look at one of the more commonly available controls, RealNetworks' RealPlayer, which comes in both plug-in form for NN and ActiveX control form for IE. You can find more information on this control from www.realnetworks.com/ devzone/index.html, and there is a free version (RealOne Player) that can be downloaded from www.realnetworks.com. Note that a version you can pay for with more features is provided, but if you search the website, a no-charge basic version is available.
First we need to embed the control in a web page. Type the following into a text editor:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <object classid="clsid:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA" id="real1" width="0" height="0"> <param name="height" value="0"> <param name="width" value="0"> <embed name="real1" id="real1" border="0" controls="play" height=0 width=0 type="audio/x-pn-realaudio-plugin"> </object> </head> <body> <noembed> <h2>This Page requires a browser supporting Plug-ins or ActiveX controls</h2> </noembed> </body> </html>
Save this code as realplayer.htm.
The first thing to note is that the <embed> tag for the NN plug-in has been inserted in between the opening <object> tag and closing </object> tag. The reason for this is that NN will ignore the <object> tags and just display the plug-in defined in the <embed> tag. IE, on the other hand, will ignore the <embed> tag inside the <object> tags, but IE will display the ActiveX control.
IE does support the <embed> tag, though its use is discouraged. This means that if we placed the <embed> tag outside the <object> tags, IE would recognize both the <object> and <embed> tags and get confused, particularly over the id values because both have the same id of real1.
We've placed the <embed> and <object> tags inside the <head>. Why?
Well, for this example we don't want to display the graphical interface of the control itself; instead we just want to use its ability to play sounds. By placing it inside the head of the document, it becomes invisible to the user.
Finally, we've put a <noembed> tag inside the body of the page for users of browsers that don't support plug-ins or ActiveX controls. This will display a message to such users telling them why they are staring at a blank page!
We want to make sure that users without the RealPlayer plug-in or control don't see error messages when we start scripting the controls. So let's redirect them to another page if they do not have the right plug-in or control. We'll do this by adding a function to check for the availability of the plug-in or control and attaching this to the window object's onload event handler in the <body> tag.
</object> <script language=JavaScript type="text/javascript"> function window_onload() { var plugInInstalled = false; if (navigator.appName.indexOf("Microsoft") == -1) { var plugInCounter; for (plugInCounter = 0; plugInCounter < navigator.plugins.length; plugInCounter++) { if (navigator.plugins[plugInCounter].name.indexOf("RealPlayer") >= 0) { plugInInstalled = true; break; } } } else { if (real1.readyState == 4) { plugInInstalled = true; } } if (plugInInstalled == false) { window.location.replace("NoRealPlayerPage.htm"); } } </script> </head> <body onload="return window_onload()"> <noembed>
In the window_onload() function, we first define a variable plugInInstalled and initialize it to false.
Next, since checking for plug-ins or controls is very browser-dependent, we check to see if this is a Microsoft browser. If not, we assume it's Netscape Navigator, though for a real-life example we might want to do more detailed checks.
If the browser is Netscape Navigator, we use a for loop to go through the navigator object's plugins array, checking each installed plug-in's name for the word "RealPlayer." If this word is found, we set the variable plugInInstalled to true and break out of the for loop.
If we found that this was a Microsoft browser, we use the readyState property of the <object> tag's Object object to see if the ActiveX control is loaded, initialized successfully, and is now ready for action. If its value is 4, we know that all systems are ready to go, and we can use the control, so we set the variable plugInInstalled to true.
Finally, the last if statement in the function checks to see if plugInInstalled is true or false. If false, the user is redirected to another page called NoRealPlayerPage.htm where we can either provide alternative ways of displaying the content or provide a link to load the RealPlayer control. Let's create a simple page to do this.
<html> <head> <title>No Real Player Installed</title> </head> <body> <h2>You don't have the required RealPlayer plug-in</h2> <p> You can download the plug-in from <A href="/">Real Player</A> </p> </body> </html>
Save this as NoRealPlayerPage.htm.
Finally, back in the realplayer.htm page, let's enable the user to select a sound file as well as start and stop playing it. We add the following code to the top of the script block:
<script language=JavaScript> var fileName = ""; function butPlay_onclick() { document.real1.SetSource("file:///" + fileName); document.real1.DoPlay(); } function butStop_onclick() { document.real1.DoStop(); } function file1_onblur() { fileName = document.form1.file1.value; } function window_onload() {
We also add a form with buttons for starting, stopping, and choosing a sound file to the body of the page.
</noembed> <form id=form1 name=form1> <input type="button" value="Play Sound" id=butPlay name=butPlay language=JavaScript onclick="return butPlay_onclick()"> <input type="button" value="Stop Sound" id=butStop name=butStop language=JavaScript onclick="return butStop_onclick()"> <input type="file" id=file1 name=file1 language=JavaScript onblur="return file1_onblur()"> </form> </body> </html>
We've completed our page, so now resave it. Load realplayer.htm into your browser and, as long as your browser supports plug-ins or ActiveX controls and the RealPlayer plug-in is installed, you should see something like that shown in Figure 15-9.
Click the Browse button and browse to a sound file with the extension .ra (spacemusic.ra is provided with the code download, or you can create your own with Real Producer Basic, also available from www.realnetworks.com). Click the Play Sound and Stop Sound buttons to play and stop the sound.
So how does this work?
The form in the body of the page contains three form elements. The first two of these are just standard buttons, but the last is a <input> element of type="file". This means that a text box and a button are displayed. When the button is clicked, a Choose File dialog box opens, allowing you to choose the .ra file you want to hear. When chosen, this file's name appears in the text box.
We've connected the two buttons' onclick event handlers and the file control's onblur event handler to three functions, butPlay_onclick(), butStop_onclick(), and file1_onblur(), which are defined in the script block in the head of the page.
In the function file1_onblur(), we set a global variable, fileName, to the value of the file control. In other words, fileName will contain the name and path of the file the user has chosen to play. The onblur event will fire whenever the user moves focus from the file control to another control or area of the page. In reality we would perform checks to see whether the file type selected by the user is actually a valid sound file.
In the other two functions, we access the RealPlayer plug-in or control that we embedded in the page. We use one function to load the file the user selected and play it, and the other function to stop play.
In both functions, we access the RealPlayer control by using its name prefixed with document. The script will work with IE and NN, though under IE it's accessing the ActiveX control defined in <object>, and in NN it's accessing the plug-in defined in the <embed> tag.
In the butPlay_onclick() function, we use the SetSource() method of the RealPlayer object. This method takes one parameter—the file that we want the RealPlayer plug-in to load. So, in the line
document.real1.SetSource("file:///" + fileName);
we load the file the user specified. Next we use the DoPlay() method of the RealPlayer object, which starts the playing of the source file.
document.real1.DoPlay();
In function butStop_onclick(), we stop the playing of the clip using the DoStop() method of the RealPlayer object.
document.real1.DoStop();
It's quite likely that if you plan to use an ActiveX control or plug-in, you're going to make sure it's installed on your computer. The problem is that while that's great for testing pages to see they work when there is a control installed, it does make it very difficult to check redirection scripts for users without that control. You have a number of possible options:
Get a second computer with a clean install of an operating system and browser, then load your pages on that computer. This is the way I do it, as it's the only 100-percent sure way of checking your pages.
Uninstall the plug-in. Depending on how the plug-in/control was installed, there may be an uninstall program for it. For Windows users, there is the Add/Remove programs option in the Control Panel.
For Netscape browsers, install a different version of the browser. For example, if you have Netscape 7.1 installed, try installing an older version, say Netscape 6.2 or even 4.7 if you can find it. The plug-ins currently installed are not normally available to a browser installed later, though this may not be true all of the time.
With IE, you can only have one version of the browser installed at once. However, IE does make it quite easy to remove ActiveX controls. In IE 5 and 6, choose Internet Options from the Tools menu. Click the Settings button under Temporary Internet files, followed by the View Objects button. From here you need to right-click on the name of the control you want removed and select Remove from the popup menu.
Plug-ins and ActiveX controls provide a great way to extend a browser's functionality, but they do so at a price—compatibility problems. Some of the problems that might be faced are discussed in the following sections.
Although a plug-in for NN and the equivalent ActiveX control for IE may support many similar properties and methods, you will often find significant, and sometimes subtle, differences.
For example, both the plug-in and ActiveX control version of RealPlayer support the SetSource() method. However, while
document.real1.SetSource("file:///D:\\MyDir\\MyFile.ra")
will work with IE, it will cause problems with NN. To work with NN we must specify the protocol by which the file will be loaded. If it is URL, we need to specify http://, but for a file on a user's local hard drive we need to add file://.
To make the code work for both IE and NN, we must type
document.real1.SetSource("file://D:\MyDir\MyFile.ra")
When scripting the RealPlayer plug-in for NN, we embedded it like this:
<embed name="real1" id="real1" border="0" controls="play" height=0 width=0 type="audio/x-pn-realaudio-plugin">
We then accessed it via script just by typing this:
document.real1.DoPlay()
However, if we are scripting a Flash player, we need to add the attribute
swliveconnect=true
to the <embed> definition in the HTML, otherwise any attempts to access the plug-in will result in errors.
<embed name="map" swLiveConnect=true src="topmenu.swf" width=300 height=200 pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_ Version=ShockwaveFlash">
It's very important to study any available documentation that comes with a plug-in to check that there are no subtle problems like this.
Support for ActiveX controls varies greatly between different operating systems. IE for the Apple Mac does, but not as well as with Win32 operating systems, such as Windows 95, 98, 2000, and XP.
Also, we need to be aware that an ActiveX control written for Win32 will not work on the Apple Mac; we need to make sure a Mac-specific control is downloaded.
IE on the Mac supports plug-ins as well as ActiveX controls, so, for example, Flash is a plug-in on the Mac and an ActiveX control on Win32. Clearly, if we want to support both Mac and Windows users, we need to write more complex code.
It's very important to check which operating system the user is running (for example, using the scripts given at the end of Chapter 5) and deal with any problems that may arise.
Creators of plug-ins and controls will often periodically release new versions with new features. If we make use of these new features, we need to make sure that the user not only has the right plug-in or ActiveX control loaded, but also that it's the right version.
With ActiveX controls, we can add version information in the codebase attribute of the <object> tag.
<object classid=clsid:AAA03-8BE4-11CF-B84B-0020AFBBCCFA id=myControl codebase="http://myserver/mycontrol.cab#version=3,0,0,0"> </object>
Now, not only will the browser check that the control is installed on the user's system, but it'll also check that the installed version is version 3 or greater.
What if we want to check the version and then redirect to a different page if it's a version earlier than our page requires?
With ActiveX controls there's no easy way of using JavaScript code to check the ActiveX control version. One way is to find a property that the new control supports but that older versions don't, and then compare that to null. For example, imagine we have a control whose latest version introduces the property BgColor. To check if the installed version is the version we want, we type
if (document.myControl.BgColor == null) { alert("This is an old version"); }
It's also possible that the ActiveX creator has added a version property of some sort to his control's object that we can check against, but this will vary from control to control.
With plug-ins we need to make use of the Plugin objects in the navigator object's plugins[] array property. Each Plugin object in the array has a name, filename, and description property, which may provide version information. However, this will vary between plug-ins.
For example, for Flash Player 4 on Win32 the description given by
navigator.plugins["Shockwave Flash"].description
is Flash 4.0 r7.
Using regular expressions, which we introduced in Chapter 8, we could extract the version number from this string
var myRegExp = /\d{1,}.\d{1,}/; var flashVersion = navigator.plugins["Shockwave Flash"].description; flashVersion = parseFloat(flashVersion.match(myRegExp)[0]);
In the first line of code we define a regular expression that will match one or more digits, followed by a dot, and then one or more numbers. Next we store the description of the Flash plug-in in the variable flashVersion. Finally we search the variable for the regular expression, returning an array of all the matches made. We then use the parseFloat() function on the contents of the element in the array at index 0 (in other words, the first element in the array).
For mostly legal reasons Microsoft is making changes to how ActiveX controls work in IE. Now whenever a user browses to a page with an ActiveX control, she gets a warning about the control, and by default it's blocked unless the user choose to unblock it. There are two ways around this:
Don't access any external data or have any <param> tags in the definition, as the following example shows:
<object classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6"></object>
Use the new noexternaldata attribute to specify that no external access of data is used.
<object noexternaldata="true" classid="CLSid:6BF52A52-394A-11d3-B153-00C04F79FAA6"> <param name="URL" value="http://msdn.microsoft.com/workshop/samples/author/dhtml/media/drums.wav"/> </object>
The URL parameter will be ignored, and no external data from the URL, in this case a .wav file, will be accessed.