Creating Command Extensions

[ LiB ]

Commands are extensions that appear as entries on the Commands menu. (Actually, if you manipulate the menus .xml file, as discussed in the previous chapter, you can make commands appear on any menu. But they appear on the Commands menu by default.) They are the most versatile and powerful of the extension types, allowing you to perform almost any edits on a document or site. Their API requirements are simple, but because they are so flexible, they are not easy to master. This section covers what's involved in creating simple (and also not-so-simple) Dreamweaver commands.

Commands in the Configuration Folder

Like all extensions, commands are made from HTML and JavaScript. Each command consists of an HTML file (the command file itself) and optional, associated JS files and/or graphics. Command files are stored in the Configuration/Commands folder. By default, all files in this folder appear on the Commands menu.

If you have ever recorded commands or saved history steps as commands, you've created simple command files! Look in your user -specific Configuration/Commands folder, and you'll find an HTML file for every saved command. The filename is the name you gave the command when you saved it.


The API for Commands

Like objects, commands can exist with or without dialog boxes. They can be simple or complex. A number of API-defined functions can be part of the command file, but the file also can be very simple, with no special functions. The API procedure is simple or complex, based on the file structure. (Note also that these are flexible extensions!)

Command File Structure

There are no required API functions for commands, although a variety of optional functions exist. Figure 29.10 shows a very basic command file, with only required elements in place. Note that the body section is empty. Note also that there are no API functions, and the main function is called onLoad .

Figure 29.10. The HTML file for a simple command that does not call a dialog box.


This kind of file has the following elements:

  • Filename The filename, minus its extension, becomes the menu entry. Command filenames can include spaces, and capitalization is respected.

  • Main function This is the function that makes the command do whatever you want it to do. It's a locally defined function, not part of the API, which means that it must be called explicitly. If the command has no dialog box, the function should be called in the <body> tag, using the onLoad event handler. If the command has a dialog box, the function should be called as part of the commandButtons() function (described in the following list).

Believe it or not, that's all that's absolutely required of a command file without a dialog box.

If the command includes a dialog box, a few more API elements are required. Figure 29.11 shows a sample command file with a dialog box, again containing only the necessary elements. Note that the form does not include a Submit button. The main command is now called from the commandButtons() function, not from the <body> tag.

Figure 29.11. The HTML file for a command that calls a dialog box.


The required elements for a command that calls up a dialog box are as follows :

  • Page title The title is required if the command includes a dialog box. It becomes the title of the command's dialog box if there is one. If there isn't a dialog box, the title is not required.

  • HTML form As with all extensions, this creates the user interface (in this case, the dialog box). Note that, as with objects, the form does not include a Submit button. Unlike objects, however, command dialog boxes are not automatically supplied with buttons; instead, command buttons must be defined and given functionality using the commandButtons() function.

  • commandButtons() function If there is a dialog box, this function creates the buttons that appear. If this function doesn't exist, the user will have no way to activate or close the dialog box! The command Buttons() function must return an array consisting of the name of each button, followed by the code to be executed when the button is clicked. Note that because the main command function must be called here, it should no longer be called using the <body> tag's onLoad handler.

In addition to these required elements, several optional API functions can be included. The most useful of these is canAcceptCommand() . This function determines whether the command should appear grayed-out (disabled) in the menu. A command that operates on the contents of a document, for instance, shouldn't be accessible if a document isn't open . If the function returns true, the command is accessible; if it returns false, the command is grayed-out. The API includes a whole slew of enablers (functions that determine whether something is possible) to help with this.

The Procedure for Commands

The API procedure for processing commands determines how and when Dreamweaver uses the file elements discussed in the preceding section. The procedure is as follows:

  1. When the user clicks the Commands menu, Dreamweaver looks through all files that should appear on the Commands menu, checking each for the canAcceptCommand() function. If it's present, and if it returns false, that command is grayed-out in the menu. If it's not present, or if it returns true, the command is available.

  2. When the user chooses a command from the menu, if there is no form, Dreamweaver executes whatever function is defined in the <body> tag's onLoad handler, and the procedure is complete.

  3. If the command file includes a form, Dreamweaver calls the commandButtons() function to determine what buttons to add to the form. It calls any function called onLoad (such as an initializeUI() function). It then presents the dialog box, displaying the <title> in the dialog box's title bar.

  4. When the user clicks any of the buttons in the dialog box, Dreamweaver executes the code attached to that button by the commandButtons() function. Typically, an OK button calls the main function and closes the window, an Apply button calls the main function but doesn't close the window, and a Cancel button just closes the window. Note that the dialog box does not close until one of the buttons uses the window.close() statement.

So far, it all sounds pretty simple. The complex aspect of commands is that you usually want them to act on documents. And acting on documents means dealing with the Dreamweaver DOM.

The Dreamweaver DOM

If you've ever torn your hair out struggling with the conflicting DOMs of Internet Explorer and Netscape, working with Dreamweaver commands will be a welcome relief, because there's only the Dreamweaver DOM to worry about.


If you've worked in depth with JavaScriptespecially if you've created DHTML effects using JavaScriptyou're already familiar with the concept of the document object model (DOM) . The DOM is the hierarchical, or tree, structure of objects (tags, pieces of text, and so on) that makes up an HTML document. To gain access to any part of the document, you must navigate up and down the hierarchy, or climb up and down the tree.

Understanding Objects (Nodes)

An object is any page element that you can control by scripting. They have properties that you can access and change and methods that represent things you can do with them. Objects are also called nodes .

Parents, Children, and Siblings

Just as an HTML document is constructed from tags nested inside each other, and text blocks nested inside tags, so objects, or nodes, can have parents, children, and siblings. In the following example, the <ul> object is the parent node of the three <li> objects, which are siblings of each other:

 <ul>     <li>Moe</li>     <li>Larry</li>     <li>Curly</li> </ul> 

The text block Moe is the only child node of the first <li> object, and so on. Figure 29.12 shows a typical document diagrammed as a tree of objects.

Figure 29.12. A simple HTML document shown as it appears in Dreamweaver and as a diagrammed document tree.


Node Types

A document has four kinds of objects, or nodes:

  • The document node type The document itself, as an entity.

  • The element node type All HTML tags belong to this type.

  • The text node type Each block of text is an object of this type.

  • The comment node type HTML comments.

In the earlier example, the Moe object is of the text node type; its parent <li> object is of the element node type. Different node types have different properties and methods. Tables 29.1 through 29.4 list the properties and methods of the different node types as they exist in the Dreamweaver DOM.

Table 29.1. DOCUMENT_NODE Objects

Property/Method

Return Value

Read-Only?

nodeType

9

Yes

parentNode

Null

Yes

parentWindow

An object representing the document's parent window

Yes

childNodes

A NodeList containing all children

Yes

documentElement

The <html> tag element

Yes

body

The <body> tag element

No

URL

The document's absolute address (or an empty string if the document hasn't been saved)

No

getElementsByTagName

A NodeList containing all instances of the given tag (tagName)

No

hasChildNodes()

true

No


Table 29.2. ELEMENT_NODE Objects

Property/Method

Return Value

Read-Only?

nodeType

1

Yes

parentNode

The parent tag

Yes

childNodes

A NodeList containing all immediate children

Yes

tagName

The tag's HTML name ( TABLE , A , IMG , and so on)

Yes

attrName

A string containing the value of the specified tag attribute

No

innerHTML

HTML code contained within the element's opening and closing tags

No

outerHTML

HTML code contained within the tag and the opening and closing tags

No

getAttributes ( attrName )

The value of the attrName attribute

No

setAttribute

attrName , attrValue

No

removeAttribute

attrName

No

getElementsByTagName

A NodeList of children of the current element that are ( tagName ) tagName elements

No

hasChildNodes()

true/false

No


Table 29.3. COMMENT_NODE Objects

Property/Method

Return Value

Read-Only?

nodeType

8

Yes

parentNode

The parent tag

Yes

childNodes

An empty NodeList

Yes

data

A string of text between the opening and closing comment tags

No

hasChildNodes()

false

No


Table 29.4. TEXT_NODE Objects

Property/Method

Return Value

Read-Only?

nodeType

3

Yes

parentNode

The parent tag

Yes

childNodes

An empty NodeList

Yes

data

A string of text that comprises the current object

No

hasChildNodes()

false

No


Gaining Access to the DOM

In addition to all the standard JavaScript means of accessing and controlling DOM objects, the Dreamweaver API includes the document, or dom , object and its methods. These are the primary methods you use to edit documents using Dreamweaver extensions. Before you can use any of these methods on a document, however, you have to officially gain access to the document's structure using the dw.getDocumentDOM() function. Table 29.5 lists the specifications for this function. This function lets you gain scripting access to the contents of user documents.

Table 29.5. Specifications for dw.getDocumentDOM()

Syntax

dw.getDocumentDOM()

Description

This function creates a DOM object, giving access to the contents of a document's object structure.

Arguments

No arguments are required. If no arguments are present, the currently active document is used as the source of the DOM object. The optional arguments are as follows:

 

document

 

parent

 

parent. frames [ number ]

 

parent.frames [' framename ']

 

A URL. (URLs must be absolute or relative to the extension file.)

Returns

The document object at the top of the DOM hierarchy ( DOCUMENT_NODE type).


You access the current user document's DOM by assigning it to a variable:

 var theDOM=dw.getDocumentDOM(); 

After you have done this, you have access to an object of the first node type previously listed. You are officially climbing the document tree. You can now use the methods and properties of the various nodes to navigate through the document and edit it, as in these examples:

 //change the background color to black var theDOM=dw.getDocumentDOM(); var theBody=theDOM.body; theBody.bgcolor="#000000"; //determine what kind of object the current selection is var theDOM=dw.getDocumentDOM(); var theSel=theDOM.getSelectedNode(); if (theSel.nodeType=="1") {       window.alert(theSel.tagName);       } else if (theSel.nodeType=="3") {       window.alert(theSel.data);       } 

The subject of DOM access is much bigger than this chapter covers, and it takes practice to master. But the rewards are great. After you know how to navigate a document, you can use your command or other extension to tell Dreamweaver to do almost anything to a user document. (Such power!)

For more information on working with the DOM, and scripting extensions in general, read Dreamweaver MX Extensions , published by New Riders, or Building Dreamweaver 4 and UltraDev 4 Extensions , published by Osborne.


Exercise 29.5. Making a Simple Command

In this exercise, you will create a command that finds all the images in an open document and assigns them a border width of 2. You won't need a dialog box, so this will be a simple file to create. You will, however, get some practice accessing the DOM.

  1. In your text editor, create a new HTML file. Enter the basic code framework for a command with no dialog box. You will leave the details blank for now (placeholder code is in italic):

     <html> <head> <title>Set Image Border</title> <script language="JavaScript"> function setImageBorder() { //  command code goes here  } </script> </head> <body onLoad="setImageBorder()"> </body> </html> 

    You set the <title> , although it won't be called on. You also create a local function, setImageBorder() , and call it onLoad . That's all the framework you need.

  2. Custom commands, like custom objects, should be saved in your user-specific Configuration folder, to keep the main Configuration folder clean. Look in your user-specific Configuration folder. If it doesn't contain a Commands folder, create a new folder there and call it Commands . Save the file you just created in your user-specific Configuration/Commands folder as Set Image Border.htm .

  3. The only remaining step is to fill in the main function code. Before accessing the DOM, plan out the required functionality for setImageBorder() . Using the dw.getDocumentDOM() function, and the node methods and properties listed in Tables 29.1 through 29.4, you can determine that your function needs to do the following (the new code is in bold):

     function setImageBorder() { //get document access //get image access (collect images as an array) //set the border property of each array item } 

    Plotting out the main steps of a function as comments inside the function can help whittle major scripting tasks into manageable chunks . This is often called pseudocode.


  4. You start by getting document access (the new code is in bold):

     function setImageBorder() { //get document access var theDOM=dw.getDocumentDOM(); //get image access (collect images as an array) //set the border property of each array item } 

  5. Next , you climb the tree to get the images. Table 29.1 shows that the document node type object has a property called body , which gives you access to the body tag. Because the images are all in the body, you'll start with that. Then, because the body tag is of the element node type, you'll use its getElementsByTagName() method to collect all the body's img tags into an array:

     function setImageBorder() { //get document access var theDOM=dw.getDocumentDOM(); //get image access (collect images as an array) var theBody=theDOM.body; var theImages=theBody.getElementsByTagName("IMG"); //set the border property of each array item } 

  6. You have now collected the images into an array of objects of the element node type. Any tag attribute can be accessed as an object property. So you can step through the image array, setting the border property to 2 (the new code is in bold):

     function setImageBorder() { //get document access var theDOM=dw.getDocumentDOM(); //get image access (collect images as an array) var theBody=theDOM.body; var theImages=theBody.getElementsByTagName("IMG"); //set the border property of each array item for (var a=0;a<theImages.length;a++) {   theImages[a].border="2";   } } 

  7. That's all there is to it! Save your document and close it. If Dreamweaver is running, quit. Then launch Dreamweaver and open a document that has several images.

What If It Doesn't Work?

If your command file contains a syntax error, Dreamweaver gives you a handy error message as soon as you try to choose the file. Read the error message, go back to your file, and find the error.

If your object doesn't cause any errors, but it doesn't change any images, there's a logic error. Probably you didn't accurately access the DOM. The getElementsByTagName() function requires that all parameters be specified in uppercase, so make sure your code refers to IMG , not img , or it won't work. Make sure all your variable names match as you proceed into the document tree. Match your code against the code shown here, and keep tinkering until it works.


Exercise 29.6. Creating a Command with a Dialog Box

The command so far is handyif users want a two-pixel border around their images. How about letting the user specify how wide the border should be? (The ability to set the border to 0 might come in handy if you ever inherit someone else's HTML pages from a web editor that doesn't set that feature automatically.) You'll now add a dialog box to the command created in the preceding exercise, asking for a width.

  1. In your text editor, open the Set Image Border.htm command file, and save it as Set Image Border 2.htm .

  2. Create a simple form in the file's body section. As always, you can code the form by hand or open the file in Dreamweaver and create the form in Design view. Figure 29.13 shows how the form might look when complete.

    Figure 29.13. The form for the Set Image Border dialog box, as seen in Dreamweaver Code and Design view.


    Wherever you create the form, remember to name it. Here, the form is named theForm , and the name of the text box is borderwidth .

  3. Because there's now a form, you need to add the commandButtons() function. You will want an OK button that calls the main function and closes the window, an Apply button that calls the main function but doesn't close the window, and a Cancel button that just closes the main window. The code looks like this:

     function commandButtons() { return new Array("OK","setImageBorder(); window.close();",  "Apply",  "setImageBorder()", "Cancel","window.close()"); } 

    After you've done this, be sure to remove the function call from the <body> tag. You don't want the main function to execute as soon as the dialog box opens!

  4. Finally, you need to adjust the main function so that it includes the form input collected in the dialog box. Rewrite the statement inside the for loop like this (the new code is in bold):

     for (var a=0;a>theImages.length;a++) { theImages[a].border=document.theForm.borderwidth.value; } 

  5. Try it out! Your dialog box should look like the one shown in Figure 29.14. Make sure that the commands get executed properly and that all three command buttons behave as they're supposed to.

    Figure 29.14. The dialog box for the Set Image Borders command.


Exercise 29.7. Refining Your Command

You can improve the functionality of this little command in all sorts of ways. Maybe you just want to set the border for images with or without links. Maybe you want to let the user choose which images get borders. Maybe you want to give the user the opportunity to remove the border attribute completely. With DOM access, all is possible. (To work with linked images, just determine which <img> tags have an <a> tag as their parent node.) For now, however, add the canAcceptCommand() function. If the current document doesn't have any images, it makes no sense for the command to be available. So you'll return true if there are images and false if there aren't.

  1. In your text editor, open the Set Image Borders 2.htm command file. Add the framework for the new function, along with an indication of what you want it to do:

     function canAcceptCommand() { //access the document //if there is no document, return false //access the body //access the images, collected as an array //if the array is empty, return false //otherwise, return true } 

  2. As you might have noticed, the first several steps are the same as those in your main function. You can just copy and paste that code into this function, and then tack on a conditional:

     function canAcceptCommand() { //access the document var theDOM=dw.getDocumentDOM(); //if there is no document, return false if (!theDOM) return false; //access the body var theBody=theDOM.body; //access the images, collected as an array var theImages=theBody.getElementsByTagName("IMG"); //if the array is empty, return false if (theImages.length=="0") return false; //otherwise, return true else return true; } 

  3. Try your command now to see how it works. First, try it on a document with images, and then on one without.

Do you get tired of repeatedly quitting and relaunching Dreamweaver every time you tweak an extension? Here's a shortcut: Ctrl-click (Windows) or Opt-click (Mac) the Insert bar's categories drop-down menu. The Reload Extensions option appears. When you choose this, the program reloads its extensions without quitting.


Making the Most of Commands

Are you already full of ideas for your next command? If so, there's no stopping you. If not, you might need to broaden your horizons a little bit. Try these inspiration generators:

  • Whenever you're working in Dreamweaver, keep a notebook handy. If you find yourself often repeating the same manual procedure, wasting time performing tedious tasks, try to imagine what kind of command you could write to help yourself out. Jot down that inspiration.

  • Take a spin through the Extending Dreamweaver manual, especially the list of API methods that takes up the last half of the book. Just seeing all the different things you can tell Dreamweaver to do is likely to get your imagination moving.

  • Unless you enjoy coding for its own sake, don't spend hours and hours writing a command before you check out the Exchange. You might come across a command that does exactly what you need.

The more you work with the DOM, the easier it will be. Pretty soon, you'll want to create custom Property Inspectors, floating panels, reports , translators, and more.

[ LiB ]


Macromedia Dreamweaver MX 2004 Demystified
Macromedia Dreamweaver MX 2004 Demystified
ISBN: 0735713847
EAN: 2147483647
Year: 2002
Pages: 188
Authors: Laura Gutman

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net