Welcome back to the second part of our Dreamweaver series. We talked about configuration issues in part one, and today we'll move forward by dissecting the first custom command to determine the document's number of words and characters.
In order to follow along with this article, you'll need Dreamweaver or Dreamweaver UltraDev version 3 or later. You can download a free 30-day evaluation copy of Dreamweaver 4 at Macromedia.
Accessing a window or document is quite easy when you're hosted inside a browser. You get a reference to a window via the frames array from properties such as "opener" or a variable. Dreamweaver must naturally take a different approach, so, in order to find the active document, you'd write:
var doc = dreamweaver.getActiveWindow();
In contrast to the method's name, it returns a DOM document rather than a window object. The
dreamweaver object is one of two generic objects inside Dreamweaver (you can also access it via the shortcut
dw). It contains properties like
appVersion and methods to operate on the application itself, rather than on documents. Another way to access a document is
getDocumentDom(), a method of the
var doc = dreamweaver.getDocumentDom("document");
This method expects one argument, which determines the document to access --
document points to the active document,
parent points to the parent frameset, and
parent.frames["framename"] points to a frame of the same frameset of the active document.
Accessing the current document works just like it does in a browser. When your code is running as a command, the current document is the dialogue shown.
Dreamweaver 3 introduced a lot of new features. One of them is a new and enhanced Document Object Model, which is a mixture of Netscape's homegrown DOM and a subset of DOM Level 1.
getElementById() method is missing in contrast to the DOM Level 1 specification. This makes accessing the DOM tree a little harder sometimes, but you can find a utility method that can be used as a workaround inside the library's archive file.
So, after finding the needed document (see above), you can access its document structure through DOM's
documentElement property. To access its HTML content, you can use either the
outerHTML property. The latter also contains the tags that make up the element:
var docRoot = doc.documentElement;
var html = docRoot.outerHTML;
The next step will tell you why I accessed
outerHTML instead of
Retrieving a document's selection is not part of the DOM specs, so we need to use proprietary methods, which are all extensions of the document object. To access the current selection you write:
var sel = doc.getSelection();
getSelection() method returns an array of pairs of byte offsets. Depending on the selection, the array has at least two fields -- a start offset followed by an end offset. More complex selections are expressed in more than one pair. The offsets are expressed in bytes beginning from the start of the selection, and can be extracted easily with a simple
substring() call (see the the full source code). Additionally, the method
getSelectedNode() can be used to retrieve the node which contains the selection.
To make the command more flexible, we check the extracted text's length. If it's zero, we assume the user wants to apply the command to the whole document instead to a selection.
Dreamweaver's Selection API also allows you to select or substring, an element, or a table programmatically.
Because we have an HTML code substring now, we need to apply regular expressions to extract the text. We start by eliminating all tags, the regexp used makes things easier, as Dreamweaver will complain about incorrect source code structure.
The next step is, due to HTML's syntax, very important: All entities have to be converted because the special characters
; would yield two additional word boundaries in our
regexp. So, the code replaces the non-breaking space with a simple white space and the rest into a dummy character.
Now, let's count the word boundaries, and we're almost done. This isn't as obvious as it might seem. The special character
\w matches all word characters, which includes "0"..."9" and "_", so it's up to you to treat it as a number, a whole list, or a table of words. If you don't want to, the
regexp has to be rewritten.
Fortunately this is also very simple as the special character for word boundaries,
\b, is found before the first character of the word and after the preceding character. Thus, we can simply replace the
[a-zA-Z]. This matches all Latin characters while
\D will match a non-digit character (which must be letter after a word boundary).
To find the length of a string, we can eliminate all white spaces in the last step and count the length of the resulting string.
The complete source code of the command can be found in our library. For instructions on how to incorporate it into your Dreamweaver program, you should refer to the preceding column.
As you can see, it's rather simple to take advantage of an open system like Dreamweaver because it uses a lot of standards you probably already know. You only have to learn about the basic framework and the custom APIs used.
While today's lesson was fairly simple, we'll talk about the file I/O APIs next time so that you can access the files of your site. We'll also show you how to create a full-featured, tree-view menu object with just a few lines of code. Stay tuned!
Copyright © 2009 O'Reilly Media, Inc.