Learning how to manipulate the Dreamweaver DOM is an important part of learning extensibility. If you're already an old hand at working with the Level 0 and Level 1 DOM, you can skip this practice session. If not, roll up your sleeves and let's get tinkering . Task 1: Create a command file to practice with For this practice session, you'll create a very simple command file that you use to experiment with the Dreamweaver DOM. (You also get your first taste of working with the API for commands.) Start by using the History panel to record a command: -
Launch Dreamweaver and create a new file. There's no need to save the file because you use it only temporarily. -
Open the History panel (Window > Others > History). The history list should be empty so far because you haven't done anything. -
In the document window, type a few random wordssomething like "This is a test." The History panel should now show your typing activity as a history step. -
In the panel, select that step. In the upper-right corner of the History panel, click the icon to access the panel's options menu and choose Save as Command. When the dialog box appears asking you to name your command, call it Test Command . Figure 4.5 shows the various steps of this process. Figure 4.5. Using the History panel to record a test command in Dreamweaver. -
Check out your new command. Look in the Command menuyour command should show at the bottom of the menu. Choose the command from the menu. Your sample text is inserted into the open document. Task 2: Examine the practice command file Commands exist as HTML files in the Configuration/Commands folder. When you record a command in Dreamweaver, the program creates a new command file in that folder. In this task, you find and open the file you just created, and use it to practice with. -
Start by minimizing, hiding, or quitting Dreamweaver. You'll be exploring your hard drive for this task. -
In multiuser environments, Dreamweaver stores recorded commands in the user 's Configuration folder, not the main Dreamweaver/Configuration folder. If you're using Windows 98 or Mac OS 9, open the Configuration folder that is stored in your Dreamweaver application folder. If you're using any other Windows OS or Mac OS X, find and open your user-specific Configuration folder. (For Windows users, look in c:\documents and settings\ username \ application data\macromedia\dreamweaver mx\configuration\ . For Mac OS X users, look in /users/ username /library/application support/dreamweaver mx/configuration .) -
Within the appropriate Configuration folder, find and open the Commands folder. Look in the list of files for a file called Test Command.htm. -
In your text editor, open Test Command.html and examine its contents. It probably looks like the file shown in Listing 4.1. Listing 4.1 Test Command.html <HTML> <HEAD> <! Portions Copyright 1999-2002 Macromedia, Inc. All rights reserved. > <TITLE>Test Command</TITLE> <SCRIPT LANGUAGE="javascript"> <! // This command was recorded by Dreamweaver MX function runCommand() { // Typing: This is a test. dw.getDocumentDOM().insertText('This is a test.'); } // > </SCRIPT> </HEAD> <BODY onLoad="runCommand()" > </BODY> </HTML> note Refer to the section "Multiple Configuration Folders" in Chapter 1 for more on Dreamweaver in multiuser operating systems. The functionality of the command is contained in the runCommand() function, which is defined in the document <head> and called as part of the <body> tag. The single statement in the function is a shorthand presentation of two statements: dw.getDocumentDOM().insertText('This is a test.'); In its standard form, the code would look like this: var myDOM = dw.getDocumentDOM(); myDOM.insertText('This is a test.'); The first statement officially gains access to the DOM object (as discussed previously); the second statement uses a method of the DOM object to insert text at the user's insertion point. Can you see how the command works? -
Strip out the file's comments and the statement inside the runCommand() function. Your test command is now ready for action! Task 3 : Practice gaining access to different document elements For this task, you'll alter the Test Command you just created to make it perform various DOM- related activities on a Dreamweaver document. Before you can go through the steps in this task, you'll need a Dreamweaver document to examine. Any file will do, although more complex files might be confusing to work with. The examples here use the dompage.html file (the same document shown in Figure 4.3 and Figure 4.4). If you want your results for this task to match the examples exactly, you can download dompage.html and its images from the companion web site to this book (www.newriders.com), or you can create a file with the same page structure (a table with two rows and two columns ) containing your own text and images. -
In Dreamweaver, open dompage.html or whatever other test file you want to practice on. In your text editor, open Test Command.htm. For the practice session, you can leave both files open, switching between them to try new commands and check them out. -
Access the <html> tag. In your text editor, bring the Test Command file to the front. Rewrite the runCommand() function to access the document's <html> tag, like this (new code is in bold): function runCommand() { var myDOM = dw.getDocumentDOM(); var myHTML = myDOM.documentElement; window.alert(myHTML); } -
Try it out. Save the file. In Dreamweaver, reload extensions and choose your test command from the Commands menu. You end up with a dialog box like that shown in Figure 4.6, indicating that you have access to an object on the page. Figure 4.6. Alert window showing that a command has accessed an object element. Now it's time to gain some information about the accessed object. As an object in the DOM, the <html> tag is an instance of a node, so it has various node properties. You can, for instance, ask what the object's node type is. -
Change the code in your test command to look like this (new code is in bold): function runCommand() { var myDOM = dw.getDocumentDOM(); var myHTML = myDOM.documentElement; var myNodeType = myHTML.nodeType; window.alert( myNodeType ); } Reload extensions in Dreamweaver, and try out the revised test command. The alert window reports a 1 . Do you know why? -
The <html> tag is an instance of the ELEMENT_NODE node type, so it partakes of all the properties listed in Table 4.4. Change the code in your test command to look like this (new code is in bold): function runCommand() { var myDOM = dw.getDocumentDOM(); var myHTML = myDOM.documentElement; var myTagName = myHTML.tagName; window.alert( myTagName ); } Can you tell, even before trying it out, what this command will cause to appear in the alert window? After you've made your guess, reload extensions in Dreamweaver and try the command. Next, try to access a child node. According to the Level 1 DOM, the <html> has two children (that is, tags nested directly under it): <head> and <body> . You can access the <body> directly by using the DOM object's body property (refer to Table 4.2). But to access the <head> , you need to do a little more work. Do it this way, building on what you already have: -
First, get a list of the <html> tag's children, like this (new code is in bold): function runCommand() { var myDOM = dw.getDocumentDOM(); var myHTML = myDOM.documentElement; var myChildren = myHTML.childNodes; } -
The childNodes property returns a nodeList, which is an array of objects. As you can see by checking Table 4.1, nodeLists have one property, length , which reports the number of items in the array; and one method, item() , which allows access to each item in the array. So add another line to your function (new code is in bold): function runCommand() { var myDOM = dw.getDocumentDOM(); var myHTML = myDOM.documentElement; var myChildren = myHTML.childNodes; var myHEAD = myChildren.item(0); } -
These statements give you access to the <head> tag. To make use of that access, ask the child object for its tag name (new code is in bold): function runCommand() { var myDOM = dw.getDocumentDOM(); var myHTML = myDOM.documentElement; var myChildren = myHTML.childNodes; var myHEAD = myChildren.item(0); window.alert(myHEAD.tagName); } Try the command out! The alert window should look like the one shown in Figure 4.7. Figure 4.7. Alert window, showing that a command has accessed the tag name of an object. note Note that the code shown here could also have been written in abbreviated formfor instance: function runCommand() { var myHTML = dw.getDocumentDOM().documentElement; var myHEAD = myHTML.childNodes.item(0); window.alert(myHEAD.tagName); } Finally, try searching for a specific type of element. Using the Level 0 DOM, you can access certain types of element, like forms and images, by using the document's built-in array of those items. A more thorough way of searching for a specific type of item in Level 1 DOM is with the getElementsByTagName() method. This function also returns a nodeList of objects that can be stepped through and accessed. -
Rewrite your function to gain access to all the table cells on the page (new code is in bold): function runCommand() { var myDOM = dw.getDocumentDOM(); var allCells = myDOM.getElementsByTagName('TD'); } -
To test out your access, ask for some information from one of the table cells (new code is in bold): function runCommand() { var myDOM = dw.getDocumentDOM(); var allCells = myDOM.getElementsByTagName('TD'); myCell = allCells.item(0); window.alert("My alignment is " + myCell.align); } -
From here, gain access to the cell 's contents and ask a few questions about them: function runCommand() { var myDOM = dw.getDocumentDOM(); var allCells = myDOM.getElementsByTagName('TD'); myCell = allCells.item(0); myContents = myCell.childNodes.item(0); window.alert("My alignment is '" + myCell.align +".'\nMy contents are node type '" + myContents.nodeType + ".'"); } Figure 4.8 shows the resulting alert window this function will generate if you're using dompage.html as your test document. Figure 4.8. Gaining access to the first table cell on the page, and determining its alignment and contents. Task 4: Practice Altering Page Elements Now that you know how to get access to different page elements, it's a small step forward to alter those elements. -
To change the default colors of your document, rewrite your function like this: function runCommand() { var myBODY = dw.getDocumentDOM().body; myBODY.bgcolor = "#000000"; myBODY.text = "#FFFFFF"; } Can you see how the function first gains access to the <body> element and then changes its properties? -
To add a border to the table in the document, rewrite your function like this: function runCommand() { var myDOM = dw.getDocumentDOM(); var allTables = myDOM.getElementsByTagName('TABLE'); allTables.item(0).border="2"; } -
To change the alignment of all table cells within the document, rewrite your function to step through the document's array of TD tags, like this: function runCommand() { var myDOM = dw.getDocumentDOM(); var allCells = myDOM.getElementsByTagName('TD'); for (var a=0;a<allCells.length;a++) { allCells.item(a).align="right"; } } Task 5: Practice selecting page elements Now let's try manipulating the document based on user selections, and get some practice using the selection functions detailed in Tables 4.124.14. -
To start, practice getting information about the selection. Change the function code in your command to report the current selection as offsets: function runCommand() { myDOM = dw.getDocumentDOM(); mySelection = myDOM.getSelection(); window.alert(mySelection); } To try this out in Dreamweaver, first select something in the practice document and then run the command. The alert window will always report two numbers . These are the offsets measuring the number of characters from the beginning of the document to the beginning of the selection (first number), and the number of characters from the beginning of the document to the end of the selection (second number). Try the command with various things selected, and see how the offset values change. See how the command responds when your selection is only an insertion point. -
Now try getting information about the selected node (in other words, the object that contains your selection). Rewrite your function to look like this: function runCommand() { myDOM = dw.getDocumentDOM(); myObject = myDOM.getSelectedNode(); window.alert(myObject.nodeType); } Try this out in Dreamweaver by selecting different items in the document and then running the command. Instead of offset values, Dreamweaver returns numbers (1,3,8,11) that represent the node type of the selected object. These numbers indicate that Dreamweaver has given you scripting access to the object. If the selection is a chunk of text, note that the command accesses the entire TEXT_NODE object, whether or not the entire text element has been selected. -
After you can get the selection, try setting the selection. This involves gaining access to an object and then setting the selected node. To select the first image on the page, rewrite your function to look like this: function runCommand() { myDOM = dw.getDocumentDOM(); myObject = myDOM.images[0]; myDOM.setSelectedNode(myObject); } Try the command out in Dreamweaver to make sure it works. -
After you have the object selected, try changing it. Delete the image by adding one more line to your function: function runCommand() { myDOM = dw.getDocumentDOM(); myObject = myDOM.images[0]; myDOM.setSelectedNode(myObject); myDOM.deleteSelection(); } Add a link to the image by changing that last line: function runCommand() { myDOM = dw.getDocumentDOM(); myObject = myDOM.images[0]; myDOM.setSelectedNode(myObject); myDOM.wrapTag('<a href="#">'); } -
Now try altering the image and then putting the insertion point after the image. You do this by collecting the object's selection offsets and setting the selection to begin and end at the ending offset value. Rewrite your function call to look like this (new code is in bold): function runCommand() { myDOM = dw.getDocumentDOM(); myObject = myDOM.images[0]; myDOM.setSelectedNode(myObject); myDOM.wrapTag('<a href="#">'); objectOffsets = myDOM.nodeToOffsets(myObject); myDOM.setSelection(objectOffsets[1],objectOffsets[1]); } Can you see how the offsets and node selections work? Keep tinkering and experimenting until you do. Task 6: Practice using string functions on page elements Working with the code as a string is different from working with the code as a hierarchy of objects. In this task, you'll see how that works. -
To see the difference between accessing the code as a string and accessing the objects, try a comparison. First, rewrite your function to access the document's HTML object and report the result: function runCommand() { myDOM = dw.getDocumentDOM(); myHTML = myDOM.documentElement; window.alert(myHTML); } Try this command out, and you get an alert window that looks like the one shown earlier in Figure 4.6. -
Now revise the function to access the HTML object's code as a string (new code is in bold): function runCommand() { var myDOM = dw.getDocumentDOM(); var myHTML = myDOM.documentElement; var myHTMLstring = myHTML.outerHTML; window.alert(myHTMLstring); } Try this command out and you'll get an alert window that looks like the one shown in Figure 4.9. You just accessed the document as one big fat text string! Figure 4.9. Alert window showing that a command has accessed the outerHTML string of the HTML element. -
To see the difference between innerHTML and outerHTML , revise your function like this (new code is in bold): function runCommand() { var myDOM = dw.getDocumentDOM(); var myHTML = myDOM.documentElement; var myHTMLstring = myHTML. outerHTML; window.alert(myHTMLstring); } Try this out. Can you see how the results in the alert window are slightly different? The <html> tags are missing from the returned code string. -
By combining regular object-based access and string access methods , you can easily investigate and alter specific portions of a document's code. Try rewriting your function like this: function runCommand() { var myDOM = dw.getDocumentDOM(); var allCells = myDOM.getElementsByTagName('TD'); var temp1 = allCells.item(0).innerHTML; var temp2 = allCells.item(1).innerHTML; allCells.item(0).innerHTML = temp2; allCells.item(1).innerHTML = temp1; } Can you tell, even without trying it out, what this revised function will do? If not, run the command on your practice document and see. Had enough practice? If you have the time and the inclination, practice some more. Set yourself various tasks that require selecting things, moving around the document, and getting access to different objects. The more comfortable you are working with the DOM, and the more familiar you are with the API functions that call on the DOM, the easier it is to create more complex extensions, like those in the upcoming chapters. |