CMXtraneous: JavaScript

Right on the edge of useful

Dreamweaver JSExtension SWFFile.getNaturalSize() returns null in some cases

Posted Saturday, February 19, 2005 4:24:04 PM by Danilo Celic

Danilo Celic

If you work with SWFs in your extensions, you may want to be able to determine the dimensions of the SWF so you can generate the proper HTML code. Dreamweaver has a built in object called SWFFile that has a method getNaturalSize() that is supposed to return an array that contains the width and height of the SWF. However, if there are times when you won't get an array back. It seems that if the SWF was published as a compressed movie, then you get a null returned rather than the dimensions array. So if you depend on user supplied SWFs, you won't be able to rely on SWFFile.getNaturalSize() to allow you to generate the proper dimensions for use in your code.

I had seen a question in the Dreamweaver Extension forums a while ago and found out that compressed SWFs and SWFs created by Dreamweaver's Flash Elements seemed to cause the null return rather than the SWF dimension array. Thanks to Drew McLellan who ran into this issue on a new extension he's working on for bringing up this issue again, and inspiring me to find a way around the issue so that you don't need to find out the dimensions, you let Dreamweaver do it for you automatically.

So, what can you do to get around it? Well, you may think that looking in the Flash object on the Insert bar may give you some guidance, as when you use it, you end up with code on your page that has the proper dimensions for the SWF file in it. However, you'd be a little miffed checking the code in that the object itself doesn't do that, Dreamweaver seemingly performs some magic in the background after the Flash SWF code is added to the page. The code the Flash object generates sets the dimensions to 32x32, and immediately after the insertion, Dreamweaver somehow makes the changes to the code reading in the proper dimensions and setting them in the code.

So with this in mind you might follow along with the logic of an object that inserts code into a page and attempt to use dom.insertHTML() to place the code into your page. Again, you'd be stymied, as that doesn't seem to trigger the resetting of the SWF's code by Dreamweaver. Ok, if you're like me, you carry on with thinking through the problem, so if an object can do this, can I call an Object file to do the code insert for me? The answer to that would be: "yes...but". You can invoke an Object from your extension using dom.insertObject() passing in the name of the object file to run (minus the file extension). The "but" part of the answer is that you need to use the objectTag() type of Object to insert code into your page, as the insertObject() type of Object forces you to use dom.insertHTML() or some other method of code insertion. Doing with insertObject() causes Dreamweaver to do the replacement for you immediately after the code is inserted into the page.

So you have a workable solution, but you may need to be able to pass along the path to the SWF file to your Object that inserts your SWF code for you. Unfortunately dom.insertObject() doesn't allow for passing of parameters as dw.runCommand() and dwscripts.callCommand() do. So one way around this would be to attach a new property to the MM global object, say MM.my_flash_path, and then in the object take that value, and use it in the creation of the code to insert into the page.

Create an extension, and use whatever code you need to to get the path to a SWF file, then call dom.insertObject() and pass in the name of your Object. The following code just uses a default document relative path to the SWF, and calls an Object whose file name is blankFlash.htm. It doesn't matter which folder within the Object folder your Object resides, as long as it is named uniquely.

MM.my_flash_path = 'batang.swf';
var dom = dw.getDocumentDOM();
dom.insertObject('blankFlash');

Within your Object file, in this case blankFlash.htm, create an objectTag() function and pull the value out of MM.my_flash_path and create the code to insert your Object. See the following code as an example (:

function objectTag(){
  var flashFilePath = MM.my_flash_path;
  rtnStr = '<OBJECT CLASSID="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' +
' CODEBASE="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" WIDTH="32" HEIGHT="32">\n' +
'<PARAM NAME="movie" VALUE="' + flashFilePath + '"> <PARAM NAME="quality" VALUE="high">\n' +
'<EMBED SRC="' + flashFilePath +
'" quality="high" PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer" ' +
'TYPE="application/x-shockwave-flash" WIDTH="32" HEIGHT="32">'+
'</EMBED></OBJECT>';

  MM.my_flash_path = ';
  return rtnStr;
}

As you can see, the height and width are each set to 32, but when the Object is run, it will insert the code and Dreamweaver will automatically change those values to the proper ones. Plus, Dreamweaver will insert the code using your code tag and attribute case settings, so you'll get lower case tags and attributes if that's what you have set in your preferences.

Interestingly, if you try to just insert the <object> code and leave off the <embed> Dreamweaver will not perform the conversion. If you just insert the <embed> tag and no <object> wrapping tag, Dreamweaver will do the proper modifications.

Note: Your Object will be displayed in the Insert bar and be clickable, so you'll need to find some way around this if you only want to only be able to use your SWF code object through your extensions, such as checking for the MM.my_flash_path value in canInsertObject() prior to allowing the Object to run. Generally, you can include <!-- MENU-LOCATION=NONE --> at the top of your extension file to prevent it from being listed in the menus, and it does stop an object from being listed in the Objects panel, however, if you attempt to invoke an object with dom.insertObject() and it has the menu hiding code in it, you'l get an error popped up by Dreamweaver.

Category tags: Dreamweaver, Extensibility, JavaScript, Macromedia News