Dojo 1.8 Release Notes

Browser Support

The following browsers have been tested and are supported in this release. If a browser version is not listed as supported, it still may work, especially on browsers with rapid release cycles (Chrome, Firefox). Future minor releases of Dojo might include fixes to support future releases of these browsers, but we cannot guarantee it.

Desktop

  • Firefox 3.6-12
  • Safari 5-6
  • Chrome 13-21
  • IE 6-9 (Dojo 1.8.4+ also support IE10, 1.8.6+ also support IE11)
  • Opera 10.50-12 (Dojo core only)

Mobile (dojox/mobile)

  • iOS 4.x, 5.x (Mobile Safari) (including all Dijit widgets except Editor)
  • Android 2.2-2.3, 3.1-3.2, 4.0-4.1
  • Blackberry 6-7
  • Mobile compatibility on desktop browsers: IE 8-9, Firefox 4-12, Safari 5-6, Chrome 13-19

TODO: Link to page with specific vendor device models tested on

Server-Side Platforms

  • While not a browser, Dojo 1.8 also works inside Node 0.6.x and 0.8.x.

Dojo

dojo/dojo (the dojo AMD loader)

  • packageMap was deprecated in lieu of the proposed AMD standard map configuration; see AMD map
  • module-level configuration as per the proposed AMD standard
  • legacy asynchronous performance has been improved.

dojo/_base/Deferred

  • dojo/_base/Deferred was deprecated in lieu of dojo/Deferred. It was updated to utilize the new promise architecture and maintains its legacy API, but developers should transition to dojo/Deferred. Also, dojo/_base/Deferred::when() has been deprecated in lieu of dojo/when.

dojo/_base/xhr

  • dojo/_base/xhr was deprecated in lieu of dojo/request/xhr. It was updated to utilize the new request architecture, but developers should transition to dojo/request/xhr.

dojo/_base/sniff

  • dojo/_base/sniff was deprecated in lieu of dojo/sniff. It was updated to utilize the new sniff module, but developers should transition to dojo/sniff.

dojo/dnd

  • dojo/dnd was enhanced to work on touch devices.

dojo/Deferred

  • A new implementation of dojo/Deferred based on dojo/promise. It only supports the “modern” promise syntax (e.g. .then() instead of .addCallback() and .addErrback()). It is strongly recommended that you migrate from dojo/_base/Deferred and adopt the new API. See dojo/Deferred.

dojo/DeferredList

  • While dojo/DeferredList is not changed, it is deprecated in lieu of dojo/promise/all and dojo/promise/first.

dojo/hccss

  • The dijit/hccss module has moved to dojo core, with a stub left in dijit for backwards compatibility.

dojo/html

  • dojo/html::_ContentSetter is now async aware when it comes to parsing content being set. The promise returned from dojo/parser::parse() will be stored in parseDeferred. If using _ContentSetter directly, ensure that you use the parserDeferred to detect when the parsing is actually complete. For example:
require(["dojo/html", "dojo/when"], function(html, when){
  var setter = new html._ContentSetter({
    node: someNode,
    parseContent: true
  });
  setter.set(someContent);
  when(setter.parseDeferred, function(){
    // Do something
  });
});

dojo/io/iframe

  • dojo/io/iframe has was deprecated in lieu of dojo/request/iframe. It was updated to utilise the new request architecture, but developers should transition to dojo/request/iframe.

dojo/io/script

  • dojo/io/script has was deprecated in lieu of dojo/request/script. It was updated to utilise the new request architecture, but developers should transition to dojo/request/script.

dojo/node

  • dojo/node is an AMD plugin that allows easier loading of Node.js modules when running Dojo in Node.js. See dojo/node for more information.

dojo/parser

There are several enhancements to dojo/parser:

Module IDs (MIDs)

  • The Parser now supports the use of Module IDs (MID) when specifying the data-dojo-type in declarative markup (#13778). Developers should use the MID in their code to ensure future compatibility with baseless modules. See below for information on Auto Require which compliments this feature.

An example:

require(["dojo/parser", "dojo/ready", "dijit/form/Button", "dijit/layout/ContentPane"],
  function(parser, ready){
    ready(function(){
      parser.parse();
    });
  }
);
<div data-dojo-type="dijit/layout/ContentPane">
  <button data-dojo-type="dijit/form/Button">Click Me!</button>
</div>

data-dojo-mixins

  • The parser now also supports a new data-dojo-mixins attribute that allows to dynamically mixin one or several classes into the main data-dojo-type class as follows:
require(["dojo/parser", "dojox/treemap/TreeMap", "dojox/treemap/Keyboard", "dojox/treemap/DrillDownUp"],
  function(parser) {
    parser.parse();
  }
);
<div data-dojo-type="dojox/treemap/TreeMap"
  data-dojo-mixins="dojox/treemap/Keyboard, dojox/treemap/DrillDownUp"></div>

dojo/parser::construct()

  • There is also a new method construct() that is useful for when you have a widget constructor and want to apply it to a node that may or may not have data-dojo-type specified:
require(["dojo/parser", "dojo/query", "dijit/form/Slider"],
function(parser, query, Slider){
  query("input[type=slider]").forEach(function(node){
    parser.construct(Slider, node);
  }
}

Script Type “dojo/aspect”

  • The parser now fully supports the declarative script tags with a type="dojo/aspect" (#15117). This allows you to define scripts that run in line with the aspect concepts behind aspect programming used in the dojo/aspect module.

Each of the following is possible:

<div data-dojo-type="package/module" data-dojo-props="foo:'bar'">

  <!-- A script with "before" advice -->
  <script type="dojo/aspect" data-dojo-advice="before" data-dojo-method="method1" data-dojo-args="i">
    console.log("I ran before!");
    i++; // Modify an argument
    return [i]; // Return the modified argument to be used by the original method
  </script>

  <!-- A script with "around" advice -->
  <script type="dojo/aspect" data-dojo-advice="around" data-dojo-method="method2" data-dojo-args="origFn">
    return function(){ // you have to be a factory and return a function
      console.log("I ran before!");
      origFn.call(this); // With around advice, you have to call the original method
      console.log("I ran after!");
    });
  </script>

  <!-- A script with "after" advice -->
  <script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="method3">
    console.log("I ran after!");
  </script>

</div>

Note with the addition of this coupled with the support of script tags of type="dojo/on", it does mean that script tags of type="dojo/connect" are fully deprecated and will likely be dropped in 2.0. In fact, internally the parser uses dojo/aspect to accomplish a connect.

Declarative Require

  • The parser now supports the ability to require modules declaratively (#15118). This is accomplished using the <script type="dojo/require"> tag. Before the document is scanned and parsed, the parser will look for any <script> tags of type dojo/require and the parser will attempt to load any modules identified in the hash that is contained within the text of the tag and put it in the global scope. For example:
<script type="dojo/require">
  on: "dojo/on",
  "app.registry": "dijit/registry",
  Button: "dijit/layout/button"
</script>

See Parser Declarative Require for more information.

Auto Require

  • The parser now supports the ability to automatically require in modules when encountered declaratively (#14591). As the document is being scanned and parsed, but before the widgets are instantiated, the parser will automatically attempt to require in modules that it hasn’t been able to resolve a constructor for and the data-dojo-type looks like a MID (e.g. package/module).

Note Developers should really be cautious when using this features, because you are not making your dependencies clear, you may have a harder time isolating where your issue is, because the parser is automatically loading modules that you may not be consciously aware of.

By setting isDebug to true in your dojoConfig, the dojo/parser will log to the console warnings whenever it attempts to auto-load modules, so this feature is not used unintentionally.

Here is an example of the feature in action. Notice how no modules are required.

<input type="text" name="field1" data-dojo-type="dijit/form/TextBox" value="Hello World" />
<button type="button" data-dojo-type="dijit/form/Button">Button</button>

See Parser Auto Require for more information.

Async Nature of .parse()

  • Because of the nature of AMD and require(), when you use either the declarative require feature or the auto require feature, .parse() will operate in an asynchronous mode. In order to maintain backwards compatibility though, the results of .parser() continue to be an Array, but will also have a promise mixed in which is fulfilled with the results of the .parse(). For new development, the safest way to interact with .parse() is to treat the return as a promise. For example:
require(["dojo/parser"], function(parser){
  parser.parse().then(function(instances){
    // instances contains the instantiated objects
  });
});

dojo/promise

  • The new dojo/promise package introduces a new architecture for asynchronous promises (callbacks), which are the foundation for dojo/Deferred.
    • dojo/promise/Promise - Promise base class. All promises will be instances of this class. See dojo/promise/Promise.
    • dojo/errors/CancelError - Default error if a promise is canceled without a reason. See dojo/errors/CancelError.
    • dojo/promise/all - Takes multiple promises and returns a new promise that is fulfilled when all promises have been fulfilled. This essentially replaces dojo/DeferredList. See dojo/promise/all.
    • dojo/promise/first - Takes multiple promises and returns a new promise that is fulfilled when the first of these promises is fulfilled. See dojo/promise/first.

dojo/request

  • The dojo/request package introduces a new architecture for making asynchronous requests from code. The module abstracts the user, for the most part, from the actual provider that makes the request. This means the user doesn’t have to normally deal with the specifics of how the request is actually made. It builds upon the dojo/promise package.

    Requiring the dojo/request as a module will return the default provider, based on platform. Browser based platforms use dojo/request/xhr and node based platforms use dojo/request/node.

    See dojo/request for more information.

    • dojo/request/default - Returns the default provider. See dojo/request/default for more information.
    • dojo/request/xhr - The XHR provider. This is the default provider for browser based platforms. This deprecates dojo/_base/xhr. See dojo/request/xhr for more information.
    • dojo/request/node - The node provider. This is the default provider for node based platforms. See dojo/request/node for more information.
    • dojo/request/iframe - The iframe provider. This deprecates dojo/io/iframe. See dojo/request/iframe for more information.
    • dojo/request/script - The script provider. This deprecates dojo/io/script. See dojo/request/script for more information.
    • dojo/request/handlers - This module defines the handles for the responses to requests as well as provides a mechanism for registering additional handlers. The modules automatically registers javascript, json and xml. See dojo/request/handlers for more information.
    • dojo/request/notify - Creates and manages the dojo/request/* topics. See dojo/request/notify for more information.
    • dojo/request/watch - An internal module for the used for watching and managing inflight IO requests.
    • dojo/request/registry - Used mapping URIs to particular providers. Useful when certain URIs require one type of provider, but others require a different one (like cross domain scenarios), but allow the user to develop a single path in the code. See dojo/request/registry for more information.
    • dojo/request/util - A set of utilities used by the dojo/request package.

dojo/router

  • A new component for routing to different client-side “pages”. See dojo/router for more information.

dojo/sniff

  • The dojo/_base/sniff module was superseded by dojo/sniff. dojo/sniff functions the same way as the old module, except doesn’t set globals like dojo.isIE. Instead, use has("ie") etc.

dojo/Stateful

  • The class now supports custom accessors for Object properties (#15187). This is similar to the functionality in dijit/_WidgetBase. Setting a custom accessor in the format of _xxxSetter or _xxxGetter will automagically be called when set() or get() or invoked. For example:
require(["dojo/Stateful", "dojo/_base/declare"], function(Stateful, declare){
  var aClass = declare(null, {
    foo: null,
    _fooGetter: function(){
      return this.foo;
    },
    _fooSetter: function(value){
      this.foo = value;
    }
  });

  var aInstance = new aClass();

  aInstance.set("foo", "bar");
  aInstance.get("foo");
});
  • In addition, custom setters that will not be setting an attribute immediately (for example doing an XHR request to transform a value) can return a promise and the attribute watches, if any, will not be called until the promise is fulfilled.
  • There is a helper function directly setting the value of an attribute/property named _changeAttrValue that is intended for use when you have co-dependent values where calling set() is not appropriate, like when a value is set on a widget the checked state needs to change as well.

See dojo/Stateful for further information.

dojo/touch

  • The module was enhanced to support touch.over, touch.out, touch.enter and touch.leave synthetic events similar to mouseover, mouseout, mouseenter, and mouseleave.
  • In addition, touch.move on mobile was changed to work like mousemove on desktop, so that when connecting to a DOMNode:
require(["dojo/on", "dojo/touch"], function(on, touch){
  on(node, touch.move, function(e){
    // handle event here
  });
});

Note It fires whenever and only when the finger is dragged over the specified node, regardless of where the drag started. Behavior when connecting to a document is unchanged.

dojo/when

  • Transparently applies callbacks to values and/or promises. See dojo/when.

Dijit

dijit/_WidgetBase

  • Widget events, including attribute changes, are emitted as events on the DOM tree
on(dom.byId("buttonContainer"), "click", function(evt){
  var widget = registry.getEnclosingWidget(evt.target);
  if(widget){
    console.log("click on widget " + widget.id);
  }
});

See Widget events published to the DOM for details.

  • Attribute setters specified with string values can now point to sub-widgets as well as DOMNodes, for example:
dojo.declare("MyWidget",
  [dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {

  templateString:
    "<div>" +
      "<button data-dojo-type='dijit/form/Button'
        data-dojo-attach-point='buttonWidget'>hi</button>" +
      "<input data-dojo-attach-point='focusNode'>" +
    "</div>"

  // Mapping this.label to this.buttonWidget.label
  label: "",
  _setLabelAttr: "buttonWidget",

  // Mapping this.value to this.focusNode DOMNode
  value: "",
  _setValueAttr: "focusNode",
});
  • childWidget.placeAt(parentWidgetId) now works correctly, even when the parent is a container widget. I.e. placeAt() calls parentWidget.addChild(). Note that you will have problems if there is a DOMNode outside of the parent widget with the same ID as the parent widget. In that case, the id argument becomes ambiguous.

dijit/Calendar

  • Can now accept a String for the value parameter (either as an argument to the constructor, or to set(“value”, ...).
require(["dijit/Calendar"], {
  var calendar = new Calendar({value: "2011-12-25"});
});

dijit/layout/ContentPane

  • ContentPane now supports addChild() and removeChild(). However, the behavior of addChild(widget, index) is undefined if the ContentPane already contains random HTML. It’s intended to be used when the pane contains just a list of widgets, like Toolbar or BorderContainer.
  • dijit/layout/ContentPane::addChild(child) will not call resize() on the new child widgets, so it should be used carefully on ContentPanes inside of a layout widget hierarchy. Note that resize() only works on visible widgets, not hidden widgets such as unselected tabs of a TabContainer.
  • ContentPane is now async aware when setting its content via the ContentSetter.

dijit/form/DateTextBox

  • DateTextBox’s drop down Calendar no longer automatically opens upon clicking the input area, unless the hasDownArrow=false option is set (in which case that’s the only way to open the drop down Calendar). (#14142)

dijit/Destroyable

  • dijit/Destroyable is new utility mixin to track handles of an instance, and then destroy them when the instance is destroyed. The application must call destroy() on the instance in order to release the handles.

    This functionality was extracted from dijit/_WigetBase and most users will access it through dijit/_WidgetBase (or a subclass).

Example usage:

var DestroyableSubClass = declare(Destroyable, {
  constructor: function(aStatefulObject){
    var self = this;
    this.domNode = domConstruct.create("button");
    this.own(
      // setup an event handler (automatically remove() when I'm destroyed)
      on(this.domNode, "click", function(){ ... }),

      // watch external object (automatically unwatch() when I'm destroyed)
      aStatefulObject.watch("x", function(name, oVal, nVal){ ... }),

      // create a supporting (internal) widget, to be destroyed when I'm destroyed
      new MySupportingWidget(...)
    );
  }
});

dijit/Dialog

  • Sizing improved for when Dialog is too big to fit in viewport. Also, sizing automatically adjusts if users resizes the browser window. (#14147)

dijit/Editor

  • Performance fixes for editors with lots of text (#14231)

dijit/Menu

The Menu widget has two new (optional) attributes:

  • selector:

    CSS selector that specifies that the Menu should be attached, via event delegation, to matching subnodes of targetNodeIds, rather than the targetNodeIds nodes themselves.

  • currentTarget:

    (readonly) which node the menu is being displayed for

Together, they allow a single Menu to attach to multiple nodes through delegation, and for the Menu’s action to be adjusted depending on the node. For example:

require(["dijit/registry", "dijit/Menu", "dijit/MenuItem", "dojo/query!css2"], function(registry, Menu, MenuItem){
  var menu = new Menu({
    targetNodeIds: ["myTable"],
    selector: "td.foo"
  });
  menu.addChild(new MenuItem({
    label: "click me"
    onClick: function(evt){
      var node = this.getParent().currentTarget;
      console.log("menu clicked for node ", node);
    }
  }));
});

This will track right-click events on each cell of a table with class=”foo”.

Further, the targetNode’s contents can be changed freely after the Menu is created. Nodes matching the selector can be created or removed, and no calls to bindDomNode() or unBindDomNode() are necessary.

Note that, like dojo/on::selector(), you need to require() an appropriate level of dojo/query to handle your selector.

dijit/layout/TabContainer

  • You can now disable tabs by setting the disabled property of the pane:
pane.set("disabled", true);

dijit/Tooltip

The Tooltip widget has two new (optional) parameters:

  • selector:

    CSS selector that specifies that the Tooltip should be attached, via event delegation, to matching subnodes of the connectId node, rather than the connectId itself.

  • getContent():

    lets the app customize the tooltip text that’s displayed based on the node that triggered the tooltip.

These parameters allow a single Tooltip widget to display unique tooltips for (for example) each row in a table:

require(["dijit/Tooltip"], function(Tooltip){
  var tooltip = new Tooltip({
    connectId: myTable,
    selector: "tr",
    getContent: function(matchedNode){ return ...; /* String */ }
  });
});

Further, the table contents can be changed freely after the Tooltip is created. Rows can be created, removed, or modified, and no calls to the Tooltip widget are necessary.

Another example: specifying selector=".dijitTreeRow" will track mouseenter and mouseleave events on each row of a Tree, rather than merely monitoring mouseenter/mouseleave on the Tree itself.

Note that, like dojo/on::selector(), you need to require() an appropriate level of dojo/query to handle your selector.

dijit/Tree

  • New dijit/tree/ObjectStoreModel class for connecting dijit/Tree to stores with the new dojo.store API. (#13781)
  • persist=true flag also saves (and restores) selected Tree nodes (#14058)
  • New expandAll()/collapseAll() methods for expanding/collapsing all the nodes in a Tree dynamically (#14287)
  • Tree Drag and Drop now works on touch devices.

Themes - Claro

All browsers except IE now implement shading in the claro theme via CSS gradients, rather than by using images. This reduces the number of files downloaded, speeding up page load.

Also, the remaining gradient images files (for IE) no longer contain any blue. Thus, customizing claro to a different color does not require modifying those files. You are still required however to update icon files that contain the theme’s primary color, such as:

  • Checkboxes and radio buttons
  • The slider handles
  • Calendar arrows
  • Dialog and TabContainer close icons
  • etc.

Performance Improvements

There have been many performance improvements to dijit:

  • CSS gradients used in claro (see above)
  • dijit/_CssStateMixin now creates listeners at the document level, rather than separate listeners for each widget. This speeds up page instantiation time, especially on a page with many small widgets like TextBoxes, Buttons, Trees (because of the many rows of the Tree), and Menus.
  • Similar event delegation changes were made for Menu and Tree, putting the listeners on the Menu or Tree rather than each individual MenuItem/TreeNode.
  • Performance improvement for TabContainers with closable tabs, because only one close Menu is created per TabContainer, rather than one Menu per tab. Event handling was also moved to TabContainer level rather than at each individual tab.

DojoX

dojox/charting

  • A new dropLabels mode was introduced on axis. It is true by default and allows to drop superfluous labels on the axis. Note that in some cases this might slow down a bit the initial computation of the chart. You can avoid that or come back to the previous behavior by:

    • setting dropLabels to false (but then you don’t get the automatic drop labels)
    • setting minorLabels to false if you know minorLabels won’t show up anyway
  • Bars, Columns and their stacked versions as well as Pie plots now support drop shadow property.

  • dojox/charting/widget classes now inherits from dijit/_WidgetBase instead of dijit/_Widget.

  • Base class for themes is now SimpleTheme instead of Theme. Themes that require gradients still need to use Theme which now inherits from SimpleTheme.

  • Provide a styleFunc on the various plots to allow to dynamically style the plot items.

  • Improve the management of missing data point in line-based plot by providing a interpolate option.

dojox/calendar

  • A new Calendar component is introduced in dojox/calendar package. It displays events from a data store over a time duration and allows the interactive editing of the position in time and duration of these events. See dojox/calendar.

dojox/cometd

  • The CometD library has been removed from DojoX. The CometD project now maintains its own Dojo library in AMD format as part of their project. This will be available via cpm, or may be downloaded from GitHub. See: CometD Project.

dojox/dgauges

  • A new gauges package is introduced in dojox/dgauges package. It provides a fully extensible gauges framework allowing you to create your own gauges as well as predefined, ready to use gauge widgets. Both circular and rectangular gauges (horizontal and vertical) are supported. See dojox/dguages.

dojox/gantt

  • Updated source code to AMD, and refactored to use recent advances to the Dojo APIs.

dojox/widget/Calendar

  • Updated source code to AMD, and refactored to use recent advances to the Dojo APIs, for dojox/widget/Calendar and associated widgets.

dojox/data/LightstreamerStore

  • The dojox/data/LightstreamerStore has been removed from DojoX. The Lightstreamer project now maintains its own Dojo library in AMD format as part of their project. This will be available via cpm, or may be downloaded from GitHub. See: Lightstreamer.

dojox/treemap

  • A new Treemap component is introduced in the dojox/treemap package. It displays data as a set of colored, potentially nested, rectangular cells. Treemaps can be used to explore large data sets by using convenient drill-down capabilities. They reveal data patterns and trends easily. See dojox/treemap.

dojox/mobile

dojox/mobile/parser

  • stopParser

    To support dojox/mvc, the stopParser feature was added to dojox/mobile/parser. If a widget has the stopParser flag, the parser stops parsing its child widgets. dojo/parser has this capability, but dojox/mobile/parser didn’t until 1.8 to keep the code size small.

  • New data-dojo-type syntax

    dojox/mobile/parser accepts the new data-dojo-type syntax using the MID (e.g. data-dojo-type="dijit/form/Button").

  • Function type property

    dojox.mobile.parser handles function-type properties correctly. In the following example, the onClick() method of the ListItem widget is overridden by the myClick function.

<li data-dojo-type="dojox.mobile.ListItem"
    data-dojo-props='moveTo:"bar", onClick:myClick'>
    Slide
</li>

dojox/mobile/ProgressIndicator

  • ProgressIndicator was a singleton non-widget module. In 1.8, it is an ordinary widget which inherits from dijit/_WidgetBase. A new enhanced ProgressIndicator has the ability to customize size, color, and display position. See dojox/mobile/ProgressIndicator for details.

New Build Profile

  • A webkit-mobile build profile was added to eliminate IE etc. code paths from a build intended only to run on webkit-mobile devices.

To create this special build:

$ cd util/buildscripts/
$ ./build.sh releaseDir=... action=release optimize=closure profile=webkitMobile

dojox/gfx

  • The GFX API now supports clipping at shape level via the new Shape.setClip(clipGeometry) method. The possible clipping geometry types are rectangle, ellipse, polyline and path (vml only supports rectangle clipping, while the GFX silverlight renderer does not support path clipping.
  • A new Shape.destroy() method has been added to properly dispose a shape when it is not used anymore. The Group.clear() method has been updated to take an optional boolean parameter that indicates whether the group children should be disposed while clearing the group.
  • The Group.getBoundingBox() method now returns the children bounding rectangle.
  • New modules specific to the SVG and canvas renderers have been added, respectively dojox/gfx/svgext and dojox/gfx/canvasext. The purpose of these modules is to give the user access to the specific capabilities of the renderer:
    • canvasext defines new methods enabling access to the Canvas pixel manipulation API, via the new Surface.getContext(), Surface.getImageData() and the Surface.render() public method.
    • svgext defines a new Shape.addRenderingOption(option, value) that adds the specified SVG rendering option on this shape, as specified by the SVG specification.

dojox/mvc

  • The MVC API now supports binding to attributes in addition to value, along with support to transform data and support one way binding to or from a model in addition to the support for two way binding.
  • dojox/mvc/StatefulModel has been deprecated in favor of different controller options which give the developer more flexibility.

See dojox/mvc for more information.

dojox/app

  • dojox/app framework now gives a clearer MVC structure by providing application controllers (dojox/app/Controller), view objects (dojox/app/View) and integration with data model/binding (dojox/mvc):
    • dojox/app/view has been removed, use dojox/app/View to create the view instance and render view widget.
    • dojox/app/scene has been removed, dojox/app/View can have parent view and children views removing the need for a specific object.
    • dojox/app/bind has been removed, use dojox/mvc controllers which give the developer more flexibility.
    • dojox/app/Controller has been added to add more flexibility in controlling the application, several controllers are provided in dojox/app/controllers package: Load controller, Transition controller, Layout controller and History controller
    • dojox/app/widgets/Container has been added as a scrollable and layout widget.

See dojox/app for more information.

Util

  • The documentation scripts at docscripts have been deprecated and replaced with a new documentation parser that works properly with AMD modules.

util/build

The builder supports the ability to detect declarative dependencies (both auto-requirement and declarative require modules) in static files and allow the building of them into a layer (#15367). To have resources scanned for dependencies, add them to the include array of a layer and tag them as declarative:

var profile = {
  action: "release",

  packages:[{
    name: "dojo",
    location: "./dojo"
  },{
    name: "app",
    location: "./app"
  }],

  layers: {
    "app/main": {
      include: ["app/index.html"]
    }
  },

  resourceTags: {
    declarative: function(filename){
      return /\.htm(l)?$/.test(filename);
    }
  }
};

See depsDeclarative for more information.

util/docscripts

While docscripts is still included in our releases, it's deprecated, and no longer used to generate dojo's own documentation. Nor is it expected to work well with AMD modules.

The documentation is now generated using https://github.com/wkeese/js-doc-parse.git. See https://github.com/wkeese/api-viewer/blob/master/README.rst for detailed instructions.

Demos

New Demos

  • tracTreemap: a Treemap demo visualizing Trac ticket status
  • calendar: a Calendar component demo
  • todoApp: a "ToDo" application leveraging dojox/mobile, dojox/app & dojox/mvc packages
  • parserAutoRequire: a demonstration application for the auto-requirement and declarative requirement features of dojo/parser

Updated Demos

Migration Notes

dojo/parser

  • The dojo/parser can operate in an async fashion when running under async: true configuration and using auto-require or declarative require features. If the results of parse() are needed, utilise the returned promise. Also any errors encountered during the parse will be raised as a promise errback.

dijit

_WidgetBase

  • Constructor Parameters: Execution of custom setters during widget construction has slightly changed. This may affect custom widgets that adjust widget parameters in postMixInProperties().

    As before, during initialization, _setXyzAttr(val) is called for each attribute xyz is passed to the constructor where the attribute has a corresponding _setXyzAttr() function or string. The change is that the value passed is the value specified to the constructor, rather than this.xyz. In other words, given a widget like:

    declare("MyWidget", {
      this.xyz: "",
      postMixInProperties: function(){
        this.xyz = "dog";
      },
      _setXyzAttr(val){
        // ...
      }
    };
    

    and then calling the constructor with a custom value:

    new MyWidget({ xyz: "cat" });
    

    _setXyzAttr("cat") would be called, rather than _setXyzAttr("dog") as before.

StackContainer, TabContainer

  • If you have a custom StackController or TabController subclass where the buttons for each pane have nested close buttons (like TabContainer itself, with the [x] on the right of each tab), you need to either:

    1. In your subclass's definition, set buttonWidgetCloseClass to the CSS class set on your close button.
    2. If your subclass extends TabController, set the dijitTabCloseButton CSS class on your close button, otherwise set dijitStackCloseButton.
  • Due to the event delegation performance improvements, if you have a custom template for TabButton, remove the data-dojo-attach-event="..." attribute.

Tree

  • Like with Menu, in the event passed to dijit/Tree::onClick(item, node, evt), and dijit/Tree::onDblClick(item, node, evt), evt.currentTarget now refers to the Tree.domNode, rather than the TreeNode.domNode. You can access the TreeNode via the node parameter.
  • If selected TreeNodes are highlighted strangely, you've probably created the Tree programatically without calling startup(). You need to call startup() on it after it's been attached to the DOM.
  • Due to the event delegation performance improvements, if you have a custom template for TreeNode, remove the data-dojo-attach-event="..." attribute.

ContentPane

  • Because of the asynchronous nature of the dojo/parser, when setting content (.set("content", content)) and that content is required to be parsed, the function can behave in an asynchronous way. Utilise the returned promise from the function to detect when the content is fully set. This function already returned a Deferred promise, because of the asynchronous nature XHR requests, but could still behave synchronously when not setting a URL.

dojox/charting

  • dojox/charting/Theme used to be automatically required by dojox/charting/Chart. This is not the case anymore, if you use it, you need to explicitly require it in your application.

  • The new dropLabels mode of the axis is set to true by default if you experience missing labels and want to get back to previous behavior you might try to:

    • set dropLabels to false
    • set minorLabels to false if there are minorLabels that appear and were not previously

dojox/mobile

migrationAssist

  • The dojox/mobile/migrationAssist module helps you migrate your dojox/mobile applications from 1.6/1.7 to 1.8. To enable migrationAssist, all you need to do is require this module as shown in the examples below.

    Legacy mode example:

    dojo.require("dojox.mobile.migrationAssist");
    dojo.require("dojox.mobile"); // This is a mobile app.
    // ...
    

    AMD Style example:

    require([
      "dojox/mobile/migrationAssist",
      "dojox/mobile", // This is a mobile app.
      // ....
    ]);
    

    If your application uses deprecated or no longer available functions, this module detects them and displays messages in the browser console.

    Also, it tries to dynamically fix them as much as possible so that the target application can work somehow. For example, dojox/mobile/View is no longer a container-type widget, and thus you cannot use addChild to add a child widget to View. This module dynamically inserts the addChild method into View in case the application is using it.

    Note, however, that the purpose of migrationAssist is not to run the older applications as they are, but to assist migration.

The remainder of this section gives a complete list of changes in dojox/mobile that may require a modification to your application, so you can also migrate your application without using the migrationAssist module.

FixedSplitter

  • FixedSplitter.css is no longer in the themes/common folder. It is in the device themes folders. (e.g. themes/iphone/FixedSplitter.css)

FlippableView

  • FlippableView was deprecated in 1.7, and removed in 1.8. Use SwapView instead.

ListItem

  • The sync property is no longer supported. It always behaves asynchronously.
  • The btnClass property is no longer supported. Use rightIcon instead.
  • The btnClass2 property is no longer supported. Use rightIcon2 instead.

SpinWheel

  • SpinWheel.css is no longer in the themes/common folder. It is in the devices themes folder. (e.g. themes/iphone/SpinWheel.css)
  • getValue() is no longer supported. Use get("values") instead.
  • setValue() is no longer supported. Use set("values", newValue) instead.

SpinWheelSlot

  • getValue() is no longer supported. Use get("value") instead.
  • getKey() is no longer supported. Use get("key") instead.
  • setValue() is no longer supported. Use set("value", newValue) instead.

Switch

  • When you place it in a ListItem, class="mblItemSwitch" is no longer necessary.

TabBar

  • In 1.7 and prior, barType="segmentedControl" produced different UIs according to the current theme. In the iphone theme, it was a segmented control, but in other themes, it was tabs with or without icons. In 1.8, however, barType="segmentedControl" always produces a segmented control UI regardless of the current theme.

    If you still need the old behavior the following:

    barType:{ "iphone_theme": "segmentedControl", "*": "tallTab" }
    

    Should produce a segmented control for the iphone theme, and a tall tab bar for the other themes. You need to use deviceTheme.js to specify barType that way.

  • Also, if you want to hide the tab icons of the segmented control in the iphone theme, you could apply the CSS like this:

    .iphone_theme .mblTabBarSegmentedControl .mblTabBarButtonIconArea {
      display: none;
    }
    

    See test_ScrollableView-demo.html for an example usage.

TabBarButton

  • Specifying a DOM Button with the class attribute like class="mblDomButtonWhitePlus" is no longer supported. Use icon="mblDomButtonWhitePlus" instead.
  • select() and deselect() are no longer supported. Use set("selected", boolean) instead.

ToolBarButton

  • Specifying the button color style with the class attribute like class="mblColorBlue" is no longer supported. Use defaultColor="mblColorBlue" instead.
  • Specifying a DOM Button with the class attribute like class="mblDomButtonWhitePlus" is no longer supported. Use icon="mblDomButtonWhitePlus" instead.
  • select() and deselect() are no longer supported. Use set("selected", boolean) instead.

dojox/mobile/parser

  • dojox/mobile/parser no longer accepts array-type attributes like:

    <div data-dojo-type="..." labels="['A','B','C','D','E']"></div>
    

    Instead, you should specify array-type attributes as follows:

    <div data-dojo-type="..." labels="A,B,C,D,E"></div>
    

    This is the same format dojo/parser accepts.

bookmarkable

Error in the documentation? Can’t find what you are looking for? Let us know!