IDE Issue 1

From MemberWiki

Jump to: navigation, search

Contents

IDE Issue 1: Toolkit identification, configuration, loading, and initialization

Original write-up

Most of the widgets that we are looking to use with IDEs are built on top of an Ajax toolkit. For example, in 3 early samples, we looked into the date picker widget (built on Dojo), a menu widget (built on YUI), and a Google Map widget (built on Google-developed JavaScript). In most cases, one or more Ajax libraries need to be sourced into the HTML application via a <script> tag and (in some cases) some sort of library configuration and initialization must occur for the widget to work properly when deployed with the HTML page.

The question is what information will we include within our IDE standards around toolkit identification, configuration, loading and initialization. On one extreme, we could decide to steer clear of defining any standards in this area and decide that the various IDEs must take care of this somehow or other. On the other extreme, we could decide to define an industry standard for how widgets identifier the Ajax libraries that they need and how those libraries are configured, loaded and initialized.

Existing industry practice

jMaki's widget.json file includes a config property that provides information about toolkits and how they should be initialized. Here is a snippet from the information within jMaki for the Dojo date picker widget:

    'config' : {
          'type' :
           { 'id' : 'dojo', 
             'libs' : [
                   '../resources/libs/dojo/v0.4.3/djd43.js'
               ],
               'preload' : 'if (typeof djConfig ==\'undefined\') djConfig = { parseWidgets: false, searchIds: [] };',
               'resources' : [
                 '../resources/libs/dojo/v0.4.3/src'
               ]
    }, 

The jMaki engineers need to explain this in more detail, but a good guess is that libs: points to the root JavaScript file to load for Dojo, preload: provides configuration settings that are used once the Dojo file is loaded via a dynamic <script> tag, and resources: is the root folder for finding other resources needed by Dojo.

Adobe Dreamweaver proposes an <assetfile type="javascript" location="<url>"> tag to identify JavaScript files that need to be loaded.

Complexities that we might want (or not) to address

Here are some sub-issues about various complexities that we might want to address:

  • Shared use of Ajax libraries - If two widgets use the same Ajax library, we might want to (or in fact need to) ensure that the Ajax library is loaded only once and that the two widgets share the same instance of the given library. This begs the following question:
    • What happens if widgets use different variations of the same Ajax library? - Suppose one widget requires jQuery 1.5 and another one jQuery 2.3 and there is a major incompatibility between jQuery 1.x and 2.x. Suppose one widget ships with a custom version of Dojo 1.0 that only supports the features needed by that widget and another widget uses a different custom version of Dojo. (Most likely we will have to have some reasonable behavior rules on Ajax toolkits, such as what we see in the introduction chapter to the OpenAjax Hub 1.0 Specification.)
  • Dynamic loading standards for Ajax libraries - There have been at least two recent proposals to OpenAjax Alliance about having us define a standard JavaScript loader. OpenAjax Alliance hasn't taken a run at that issue yet.

Analysis

It seems like an IDE loses much of its value as a visual UI tool if it cannot automatically insert <script> tags for the necessary Ajax libraries automatically into the Web page on behalf of the user. (Same argument for other resources such as <link> tags pointing to CSS files.) For a reasonable user experience, one would hope that a user does not need to do any more than:

  • Identify an Ajax library that they want to use with their application, and thereby have the IDE make all of the widgets from that library available to the user
  • Import specific widgets from that library into the HTML document, such as via drag-and-drop
  • Customize those widgets, such as with a property inspector

Therefore, due to a strong user requirement, we are strongly inclined to provide some automation in the area of automatic loading of Ajax libraries from within the IDE.

Many common Ajax libraries have an architecture that would allow some level of automation in this area. It is common that a library has a base set of JavaScript such that it is possible to:

  • first load the base set of JavaScript for a given library
  • then load the specific JavaScript for each widget used on the Web page

(Note: some Ajax libraries have packaging features, such as dojo.require, that allow consolidation of JavaScript into a single file.)

Both jMaki and Dreamweaver have had some degrees of successful with popular Ajax libraries in this area.

Given the strong benefit to the user and the fact that many Ajax libraries have a reasonably desirable architecture in this area, it seems like we should pursue standardization.

Alternative approaches

Strawman widget metadata

The strawman proposal simply identifies a library by name and version.

<widget 
    libraryName="dojo"
    libraryVersion="0.4.3"
  >
jMaki widget metadata

jMaki identifies the library by name and points to the JavaScript files. jMaki also includes configuration information (i.e., djConfig).

    'config' : {
          'type' :
           { 'id' : 'dojo', 
             'libs' : [
                   '../resources/libs/dojo/v0.4.3/djd43.js'
               ],
               'preload' : 'if (typeof djConfig ==\'undefined\') djConfig = { parseWidgets: false, searchIds: [] };',
               'resources' : [
                 '../resources/libs/dojo/v0.4.3/src'
               ]
    }, 
Adobe Dreamweaver metadata

Adobe proposes an <assetfile location="..." referenceType="javascript"/> tag to identify the JavaScript that needs to be loaded"

  <assetfiles>
    <!--  the following asset files will get copied to the users's site when they save their document and the paths will be adjust to point to them -->

    <!-- Specifing referenceType (link, import, or javascript) will create a reference to the associated asset file in the <head> -->
    <!-- not specifying a referencetype copies the file but adds no reference to it -->
    <assetfile location="yui/2.3.1/build/menu/assets/skins/sam/menu.css" referenceType="link"/>
    <assetfile location="yui/2.3.1/build/fonts/fonts-min.css" destination="yui/build/fonts/fonts-min.css" referenceType="link"/>
    <assetfile location="yui/2.3.1/build/yahoo-dom-event/yahoo-dom-event.js" referenceType="javascript"/>
    <assetfile location="yui/2.3.1/build/container/container_core-min.js" referenceType="javascript"/>
    <assetfile location="yui/2.3.1/build/menu/menu-min.js" referenceType="javascript"/>
    <assetfile location="yui/2.3.1/build/menu/map.gif" />
  </assetfiles>

Jon's proposed resolution

Specific recommendations:

  • Only focus on workflows where there is only a single version of a given Ajax library used within a particular HTML page. For example, our primary target workflow would be situations where the entire page uses a single version of a particular library (e.g., Dojo 3.1 or YUI 1.9), but don't attempt to define metadata markup that address the ability to mix Dojo 0.4 widgets with Dojo 1.0 widgets. Assume that if a user needs a new widget from a newer version of a given library (e.g., Dojo 1.0's grid widget), then the user has to upgrade the entire page to the newer version of the library.
    • NOTE: By saying only focus, that just means where we focus. It doesn't necessarily mean that we don't allow other workflows.
  • Choose a markup approach similar to Adobe's <assetfile> that lists various widget-specific files (including the library's core JavaScript) that need to be loaded within the <head> of the HTML page. The idea is that, in general, each <assetfile> would result in the addition of a single line of code to the HTML page, such as a <script> tag or <link> tag.
    • NOTE: This simple approach neither requires that Ajax libraries and IDEs support this metadata nor restricts Ajax libraries and IDEs from supporting other similar mechanisms. If this simple approach is not sufficient for particular requirements, Ajax libraries and IDEs are fully free to invent their own mechanisms.
    • NOTE: If multiple widgets point to the same asset files, assume the IDEs will be smart enough to only load the given assets once.
    • NOTE: We might consider a feature where OpenAjaxLibrary.xml also supports something similar to <assetfile> for any files that must be loaded in order for any of the widgets to work.
    • NOTE: We need to think through how this might relate to a possible future OpenAjax standard around centralized JavaScript loading.
  • Define XML metadata markup that provides similar hooks to jMaki's libs, preload, and resources, which means markup that identifies the location of the JavaScript files to load for a given library, any JavaScript to execute before loading that library, and the location of the root directory for that library.
    • NOTE: Regarding resources, perhaps that belongs in OpenAjaxLibrary.xml instead.
    • NOTE: Regarding preload, maybe we need a library-level preload instruction within OpenAjaxLibrary.xml along with widget-level preload instructions within the widget metadata.

Here is some markup that would address the bullets listed above:

Within OpenAjaxLibrary.xml:

<library xmlns="http://ns.openajax.org/library"
  ...
  baseDirectory="...relative URL to root folder for library..."
  ...
  >
  ...
  <assetfiles>
    <assetfile type="javascript|css|..." location="<url>"/> <!-- from Adobe -->
    <!-- etc -->
  </assetfiles>
  ...
  <preload> <!-- from jMaki -->
    ...javascript logic...
  </preload>
  ...
</library>

Jonathan Bond-Caron's update

That's great work, I definitely agree that versioning should not be a focus but something to consider. I'm bothered by referring to javascript or css files as 'assets', it means nothing to me. It's business terminology and I think we should favor terminology used by W3C. I generally consider everything on the Web as a "resource" that is identified by a URI. We should model this in the XML markup, here's one possibility:

Within OpenAjaxLibrary.xml:

<resource Id="acbCompany" xmlns="http://ns.openajax.org/library"
  ...
  baseDirectory="...relative URL to root folder for library..."
  ...
  >
  ...
  <resources>
    <resource type="javascript|css|..." uri="<url>"/> <!-- from Adobe -->
    <!-- etc -->
  </resources>
  ...
  <preload> <!-- from jMaki -->
    ...javascript logic...
  </preload>
  ...
</resource>

Within OpenAjaxWidget.xml:

<resource Id="acbCompany:mywidget" xmlns="http://ns.openajax.org/widget" ...>
  ...
  <resources>
   <resource type="javascript|css|..." uri="<url>"/> <!-- from Adobe -->
    
    <!-- etc -->
  </resources>
  ...
  <preload> <!-- from jMaki -->
    ...javascript logic...
  </preload>
  ...
</resource>

Within OpenAjaxWidget2.xml:

<resource Id="acbCompany:mywidget2" xmlns="http://ns.openajax.org/widget" ...>
  ...
  <resources>
   <resource Id=acbCompany:mywidget1"/>
  </resources>
  ...
  <preload> <!-- from jMaki -->
    ...javascript logic...
  </preload>
  ...
</resource>

I also added a resource Identifier (optional or mandatory?). This has shown itself very useful in my experience to integrate ajax toolkits. The Id is used by the IDE as reference to a) update the resource b) discover new resources / widgets from a remote location. For the auto-updates to work, we'd probably need tackle library and widget versioning.

Updated proposal from JonF (2007-12-13)

Background on the new proposal

At the Gadgets TF meeting yesterday, we looked at the IBM Widgets proposal:

where there is (what I think) an interesting idea for how to address some of the problems associated with this issue. Here is a snippet:

<widget xmlns ="http://openajax.org/widget" ...>
	<require library='dojo' version="0.9">
		<config>
		       "parseOnLoad: false, isDebug: true, extraLocale: ['en-us', 'ar-sy', 'es-es', 'zh-cn']"
		</config>
	</require>
...
</widget>

This has some similarities with Adobe's <assetfile> and Jonathan's <resource>, but I like a couple of particular things with the above proposal. First, it is explicit in its name by saying that the key semantic is that it is identifying a resource that is *required*. Second, it bundles any customization information (i.e., <config>) with the resource reference.

Also, we need to take into account the fact that some leading mashup-oriented gadget formats, such as Google Gadgets, only allow you to identify the snippet that belongs in the BODY (but not the HEAD), whereas others, such as Apple Dashboard, have you provide an entire HTML file that can include the HEAD.

The new proposal (updated after phone call on 2007-12-13)

Here is a derivative proposal that builds on the above:

<widget xmlns ="http://ns.openajax.org/widget" ...>
  <requires>
    <require [type=""] [name=""] [minVersion=""] 
             [src=""] [target=""] [includeAssetReference=""]
             [sandbox=""]>
      <preload>
        ...JavaScript logic to execute before asset is loaded...
      </preload>
      <postload>
        ...JavaScript logic to execute after asset is loaded...
      </postload>
    </require>
  </requires>
...
</widget>
  • 'type' is an an enum: library | javascript | css | xsl | folder | other (we can add other options in the future) where
    • 'library' indicates an Ajax library. If provided, then either ('name' and 'minVersion') or ('src') must be provided. If ('name' and 'min_version') are provided, then look to the OpenAjax Registry to find the 'src' for the standard download place for the given library. (Note that there are three options to reference a library such as Dojo. Either use <require type="library" name="dojo".../> or <require type="javascript" src="../lib/dojo1.0/dojo.js"/> or if the widget system allows for complete HTML files (as in Apple Dashboard) then simply include a <script src="../lib/dojo1.0/dojo.js"/> line in your HTML file.)
    • 'javascript' indicates a single JavaScript file that is needed by the widget
    • 'css' indicates a single CSS stylesheet file that is needed by the widget
    • 'xsl' indicates a single XSLT stylesheet file that is needed by the widget
    • 'folder' indicates a folder whose entire contents are needed by the widget
  • 'name' - see 'library'
  • 'minVersion' - see 'library'
  • 'src' holds the relative URL for the given resource, where the base folder is the location of the widget metadata file
  • 'target' holds the relative URL within the deployed package where the resource should be placed. Defaults to the same as 'src'.
  • 'includeAssetReference' is an enum that says whether the document needs to directly reference the given resource via insertion of a new element, such as inserting a <script> element into the document for a JavaScript resource. Possible values:
    • 'auto' is the default. For 'css', 'xsl' and 'javascript', 'auto' has the same meaning as 'true'. For 'folders' and 'other', 'auto' has the same meaning as 'false'.
    • 'true' says that tools MUST insert an appropriate element into the document that references the given resource. When building new HTML documents, the resource reference usually consists of a new element within the HEAD (e.g., a new <script> element within the HEAD).
    • 'false' says that tools MUST NOT insert an element into the document that references the given resource.
  • 'sandbox' is a hint to the tool to indicate whether the given widget can co-exist within the same document as other content. Note that tools do not have to honor this hint. In particular, a mashup tool might choose to sandbox all widgets into separate IFRAMEs. Possible values:
    • 'true' - (Default) This widget can co-exist with other content
    • 'false' - The widget cannot co-exist with other content and should be put into its own execution sandbox, such as its own IFRAME (in the case of HTML)

Tools MUST insert any new elements (e.g., a new <script> element) into the document in a manner such that the processing order for the new elements matches the order of the <require> elements. If a tool's workflow involves a preprocessing step on the web page content before the page is rendered, then typically within the preprocessing step the new elements (e.g., a new <script> element) will be inserted into the target web page's HEAD in the same order as the <require> elements.

If the tool is unable to perform actions indicated by the a given <require> element, such as when unsufficient attributes are provided (e.g., the <require> element has no attributes at all), then the tool SHOULD notify the user that it was unable to process the given <require> element.

Personal tools