[OpenAjaxIDE] Adobe's support for @src and @target ...

Kin Blas jblas at adobe.com
Mon Aug 24 14:46:17 PDT 2009


The intent of this email is to describe the methods used by Dreamweaver when processing the @src and @target attributes of the <library> and <require> tags in OAM files.

We've been operating under the assumption that one day frameworks/toolkits/widgets will be distributed with widget OAM files. So for example, today, jQuery UI allows folks to download a zip file containing all of the source for its widgets and effects. This zip file contains the following structure:

css/
development-bundle/demos/
development-bundle/docs/
development-bundle/external/
development-bundle/themes/
development-bundle/ui/
js/

What we'd like to see happen is that in addition to the directories above, that they also include an OAM/OpenAjax directory:

css/
development-bundle/demos/
development-bundle/docs/
development-bundle/external/
development-bundle/themes/
development-bundle/ui/
js/
open-ajax/icons/
open-ajax/oam/

That said, we've been building sample OAM files for the widgets in the jQuery UI library. One example is the Tabs widget. The OAM file goes in the open-ajax/oam directory:

                open-ajax/oam/SpryTabs_oam.xml

and makes upward references to the required files within the zip hierarchy:


<library name="jquery-ui" version="1.7.2" src="../../" target="jquery-ui-1.7.2/" copy="false">
<require type="javascript" src="js/jquery-1.3.2.min.js" target="js/jquery-1.3.2.min.js"/>
<require type="javascript" src="js/jquery-ui-1.7.2.custom.min.js" target="js/jquery-ui-1.7.2.min.js"/>
<require type="css" src="development-bundle/themes/base/ui.core.css" target="themes/base/ui.core.css"/>
<require type="css" src="development-bundle/themes/base/ui.theme.css" target="themes/base/ui.theme.css"/>
<require type="css" src="development-bundle/themes/base/ui.tabs.css" target="themes/base/ui.tabs.css"/>
<require type="folder" src="development-bundle/themes/base/images" target="themes/base/images"/>
</library>


The example above makes use of the <library> tag for convenience, should we move the location of the open-ajax/oam directory within the zip file, we would only need to update the library @src attribute versus all <require> tags. That said, the above is the equivalent of the following <require> tags:


<require type="javascript" src="../../js/jquery-1.3.2.min.js" target=" jquery-ui-1.7.2/js/jquery-1.3.2.min.js"/>
<require type="javascript" src="../../js/jquery-ui-1.7.2.custom.min.js" target=" jquery-ui-1.7.2/js/jquery-ui-1.7.2.min.js"/>
<require type="css" src="../../development-bundle/themes/base/ui.core.css" target=" jquery-ui-1.7.2/themes/base/ui.core.css"/>
<require type="css" src="../../development-bundle/themes/base/ui.theme.css" target=" jquery-ui-1.7.2/themes/base/ui.theme.css"/>
<require type="css" src="../../development-bundle/themes/base/ui.tabs.css" target=" jquery-ui-1.7.2/themes/base/ui.tabs.css"/>
<require type="folder" src="../../development-bundle/themes/base/images" target=" jquery-ui-1.7.2/themes/base/images"/>


One thing to note about the <library> and <require> tags above is that they are making use of the @target attribute. I'll speak more about that later.

Before going on I should mention something about Dreamweaver's site model. Dreamweaver has the notion of a site. A site is basically a directory that contains other files and directories that will be placed on a server, this site directory is typically the equivalent of the site root on the server. A user can create any number of sites that Dreamweaver will manage. When a user creates a document it is typically saved somewhere within the current site the user is working with in Dreamweaver. Should a file be saved outside of a site directory, Dreamweaver treats the parent directory of that file as its site directory.

Dreamweaver uses OAM files as a set of instructions that tell it what code/markup must be inserted into an HTML document, and what assets (CSS, JS, images, etc) need to be copied into the document's site, so that the widget is functional. It should be noted that this code/markup insertion happens at design-time, outside of a browser, so in essence, Dreamweaver is generating markup/code by serializing any property values specified within the OAM file and writing them out into the appropriate spots within the <content> and <javascript> templates. The resulting text is then inserted into the document at the appropriate locations.

When a Dreamweaver user attempts to insert an instance of a widget into a document, Dreamweaver parses all <library> and <require> tags to generate a list of files it must copy into the document's site and where those files should be placed within the document's deployment area within the site.

For Dreamweaver this deployment area is typically the site-root directory, so that the assets can be shared across all documents within the site, but the user can specify any other directory within the site as the area where all widget assets should be copied.

NOTE: Dreamweaver will *NOT* copy any <require> files with an @src attribute that contains an http:// or https:// URL since the assumption is that the widget is making use of CDN assets.

Since non http/https @src paths are relative to the OAM file, it is legal for them to contain upward (../..) and downward references:


<require type="folder" src="../../images/" />
<require type="javascript" src="../../js/jquery.js" />
<require type="javascript" src="js/myWidget.js" />
<require type="javascript" src="css/myWidget.css" />


This means that Dreamweaver must calculate the highest directory level containing all assets so that it can preserve the directory structure when copying to the document's site. The directory structure must be preserved to avoid breaking image/asset paths contained within any CSS or JS files. For example, myWidget.css could contain the following CSS rule:


#foo { background-image: url(../../../images/foo.gif); }


This also means, that during path resolution, downward references may be adjusted to contain their parent directory names. So for the <require> tags above, Dreamweaver ends up copying the following file/directories to the user's site based on the <require> @src paths:


images/
js/jquery.js
widgets/myWidget/js/myWidget.js
widgets/myWidget/css/myWidget.css


Note that the "widgets/myWidget" directory references above were not mentioned in the OAM file, but were calculated during the path resolution.

According to the spec, @target attributes are optional, and are meant to specify a path relative to the web page's deployment area. If a @target attribute is not specified, it defaults to using the *RESOLVED* @src path. This means that if the site root is the deployment area, the files are copied to:


/images/
/js/jquery.js
/widgets/myWidget/js/myWidget.js
/widgets/myWidget/css/myWidget.css


If the user specified another directory (includes/widgets) within their site, the files would end up there:


/includes/widgets/images/
/includes/widgets/js/jquery.js
/includes/widgets/widgets/myWidget/js/myWidget.js
/includes/widgets/widgets/myWidget/css/myWidget.css


If @target attributes are specified, then Dreamweaver  copies the assets to the path specified *underneath* the deployment directory. So if we had:


<require type="folder" src="../../images/" target="myWidget/images" />
<require type="javascript" src="../../js/jquery.js" target="myWidget/includes/jquery.js" />
<require type="javascript" src="js/myWidget.js" target="myWidget/includes/myWidget.js" />
<require type="javascript" src="css/myWidget.css" target="myWidget/css/myWidget.css" />


The files would end up in the deployment area with the following structure:


/myWidget/images/
/myWidget/includes/jquery.js
/myWidget/includes/myWidget.js
/myWidget/css/myWidget.css


NOTE: If myWidget.css had contained relative upward references for image urls:


#foo { background-image: url(../../../images/foo.gif); }


They would be broken since the target directory structure did not preserve the structure expected by the CSS file and the upward references are attempting to refer to an image directory above the site root. This means the OAM developer must take care when specifying target paths.

Path resolution gets a bit more complicated when using <library> and <require> together since @target paths can be used on either the <library> or <require> tag, or both.  Dreamweaver approaches it like this:

- <library> @src paths are resolved.
- <require> @src paths are then prefixed with the resolved library @src path giving us the location of the required asset relative to the OAM file.
- When copying the <require> asset to the deployment area, should the require asset have an an @target path specified, that is used, otherwise, it's resolved path relative to the resolved library path is used. The deployment path for the require is then prefixed with the @target path of the library.

A bit confusing, but this can be made more clear with  the following JS pseudo-code and examples.


// Pseudo-code:

var libPath =   libTargetPath ? libTargetPath: resolvedLibSrcPath;
var reqPath = reqTargetPath ? reqTargetPath : resolvedReqSrcPath;
var deploymentPath = libPath + reqPath;


=======================================
Example 1 (No target paths)
=======================================

Use Case: OAM developer didn't bother to specify targets so assets land in the deployment area and mimic the exact directory structure used by the assets.


<require type="folder" src="../../images />
<require type="javascript" src="../../js/jquery.js" />
<library src="../../widgets/myWidget" version="1.0">
<require type="javascript" src="js/myWidget.js />
<require type="javascript" src="css/myWidget.css />
</library>


File/Directory structure to be copied:


                images/
                js/jquery.js
                widgets/myWidget/js/myWidget.js
                widgets/myWidget/css/myWidget.css


File/Directory structure to be deployed:


                /images/
                /js/jquery.js
                /widgets/myWidget/js/myWidget.js
                /widgets/myWidget/css/myWidget.css


=======================================
Example 2 (target on <library>)
=======================================

Use Case: OAM developer wants to rename the library directory containing the assets, and perhaps move some other assets into it:


<require type="folder" src="../../images target=" myWidget -1.0/images"/>
<require type="javascript" src="../../js/jquery.js" target=" myWidget-1.0/js/jquery.js" />
<library src="../../widgets/myWidget" version="1.0" target=" myWidget-1.0">
<require type="javascript" src="js/myWidget.js />
<require type="javascript" src="css/myWidget.css />
</library>


File/Directory structure to be copied:


                images/
                js/jquery.js
                widgets/myWidget/js/myWidget.js
                widgets/myWidget/css/myWidget.css


File/Directory structure to be deployed:


                /widgets-1.0/images/
                /widgets-1.0/js/jquery.js
                /widgets-1.0/js/myWidget.js
                /widgets-1.0/css/myWidget.css


=======================================
Example 3 (target on <require>)
=======================================

Use Case: OAM developer wants to rename the directories and/or files names used within the library when it lands in the deployment area:


<require type="folder" src="../../images />
<require type="javascript" src="../../js/jquery.js"  />
<library src="../../widgets/myWidget" version="1.0">
<require type="javascript" src="js/myWidget.js target="jsFiles/myWidget-1.0.js" />
<require type="javascript" src="css/myWidget.css target ="cssFiles/myWidget-1.0.css" />
</library>


File/Directory structure to be copied:


                images/
                js/jquery.js
                widgets/myWidget/js/myWidget.js
                widgets/myWidget/css/myWidget.css


File/Directory structure to be deployed:


                /images
                / js/jquery.js
                /widgets/myWidget/jsFiles/myWidget-1.0.js
                /widgets/myWidget/cssFiles/myWidget-1.0.css


=======================================
Example 4 (target on <library> and <require>)
=======================================

Use Case: OAM developer wants to re-structure the deployed directory structure so that it doesn't collide with other files that may be used in the user's site.


<require type="folder" src="../../images target="myWidget-1.0/images"/>
<require type="javascript" src="../../js/jquery.js" target=" myWidget-1.0/includes/jquery.js" />
<library src="../../widgets/myWidget" version="1.0" target=" myWidget-1.0">
<require type="javascript" src="js/myWidget.js target="includes/myWidget.js" />
<require type="javascript" src="css/myWidget.css target="themes/base/myWidget.css" />
</library>


File/Directory structure to be copied:


                images/
                js/jquery.js
                widgets/myWidget/js/myWidget.js
                widgets/myWidget/css/myWidget.css


File/Directory structure to be deployed:


                /myWidget -1.0/images/
                /myWidget -1.0/includes/jquery.js
                /myWidget -1.0/includes/myWidget.js
                /myWidget -1.0/themes/base/myWidget.css


We are going to suggest to widget/OAM developers we work with, that they should be following example 4 so that their source files and directories don't collide with user's files/directories and any other files/directories that may be deployed as the result of the user inserting a widget from another vendor.

Getting back to the example from the start of this email:


<library name="jquery-ui" version="1.7.2" src="../../" target="jquery-ui-1.7.2/" copy="false">
<require type="javascript" src="js/jquery-1.3.2.min.js" target="js/jquery-1.3.2.min.js"/>
<require type="javascript" src="js/jquery-ui-1.7.2.custom.min.js" target="js/jquery-ui-1.7.2.min.js"/>
<require type="css" src="development-bundle/themes/base/ui.core.css" target="themes/base/ui.core.css"/>
<require type="css" src="development-bundle/themes/base/ui.theme.css" target="themes/base/ui.theme.css"/>
<require type="css" src="development-bundle/themes/base/ui.tabs.css" target="themes/base/ui.tabs.css"/>
<require type="folder" src="development-bundle/themes/base/images" target="themes/base/images"/>
</library>


It would result in the following files being deployed:


                /jquery-ui-1.72/js/jquery-1.3.2.min.js
                /jquery-ui-1.72/js/ jquery-ui-1.7.2.min.js
                /jquery-ui-1.72/themes/base/ui.core.css
                /jquery-ui-1.72/themes/base/ui.theme.css
                /jquery-ui-1.72/themes/base/ui.tabs.css
                /jquery-ui-1.72/themes/base/images


Other jQuery UI OAM files, such as Accordion, Dialog, Calendar, etc follow the same target directory scheme, so as more widgets are added/deployed, they are added to this same versioned directory scheme within the deployment area of the site.

Hopefully this email makes it clearer how we (Adobe) are using the @src and @target attributes.

--== Kin ==--
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://openajax.org/pipermail/ide/attachments/20090824/569c8ab9/attachment-0001.html 


More information about the IDE mailing list