@andyberry88 andyberry88 released this May 5, 2015 · 1069 commits to master since this release

Assets 3

BladeRunnerJS 1.0 Release Candidate 1

BladeRunnerJS 1.0-RC1 is the proposed 1.0 release. It will be released as 1.0 unless any major bugs in existing features are discovered.

1.0 Features and Improvements

1.0-RC1 completes the 1.0 Roadmap which includes:

  • In-built EventHub
  • Node.js style client-side code
  • Modularised application development and workbench developer tools
  • Flat file and WAR deployment
  • Global install
  • A plugin architecture for custom asset types and bundled content

Backwards Compatability

  • The plugin API has changed considerably. Existing plugins will need to be updated to use the new API. This change does not effect application code, only Java plugins.

Other than the above, 1.0-RC1 is compatible with v0.15.4.

Bug fixes and features since v0.15.x

Changes to XML namespaces (xmlns)

The XML namespaces used for BladeRunnerJS XML config has changed to use the schema.bladerunnerjs.org domain - the old and new namespaces are shown below. All instances of the previous namespaces should be replaced with the new namespace. Apps using the old namespace will continue to work, although it has been deprecated and a warning will be logged.

http://schema.caplin.com/CaplinTrader/aliasDefinitions      -> http://schema.bladerunnerjs.org/aliasDefinitions
http://schema.caplin.com/CaplinTrader/aliases               -> http://schema.bladerunnerjs.org/aliases
http://schema.caplin.com/CaplinTrader/bundleConfig          -> http://schema.bladerunnerjs.org/bundleConfig
http://schema.caplin.com/CaplinTrader/presenterComponent    -> http://schema.bladerunnerjs.org/presenterComponent

Reviewed Plugin API

The plugin API has been reviewed and the mechanism for discovering assets has been simplified. For most users of BRJS who haven't written their own plugins this change won't have any affect, however it is a backwards incompatibility for existing plugins.


The previous AssetLocation and AssetPlugin interfaces have been replaced by a single new AssetPlugin interface.

The new AssetPlugin interface has a single method:

List<Asset> discoverAssets(AssetContainer assetContainer,
    MemoizedFile dir, String requirePrefix, List<Asset> implicitDependencies,
    AssetRegistry assetRegistry)

The discoverAssets is called by the asset discovery mechanism and is the chance for each plugin to register assets. Assets can be registered using the supplied AssetRegistry which has the following interface.

public void registerSeedAsset(LinkedAsset asset)
public void promoteRegisteredAssetToSeed(LinkedAsset asset)
public void registerAsset(Asset asset)
boolean hasSeedAsset(String requirePath)
boolean hasRegisteredAsset(String requirePath)
public Asset getRegisteredAsset(String requirePath)
public List<Asset> discoverFurtherAssets(MemoizedFile dir, String requirePrefix, List<Asset> implicitDependencies)

This provides the flexibility for each AssetPlugin to register all assets in nested directories at the same time via registerAsset or registering assets for the supplied directory and optionally using discoverFurtherAssets to allow additional directories to be discovered by other plugins that aren't already discovered by the existing BRJS plugin.

An example AssetPlugin is the CssAssetPlugin which discovers all assets in the supplied directory.

if (assetContainer.dir() == dir) {
    return Collections.emptyList();
if (!requirePrefix.contains("!")) {
    requirePrefix = "css!"+requirePrefix;
for (MemoizedFile cssFile : dir.listFiles(cssFileFilter)) {
    if (!assetRegistry.hasRegisteredAsset(FileAsset.calculateRequirePath(requirePrefix, cssFile))) {
        Asset asset = new FileAsset(cssFile, assetContainer, requirePrefix);
        assetRegistry.registerAsset( asset );

Other API changes

There have been several other minor changes to the Plugin API.

  • The abstract class ArgsParsingCommandPlugin has been renamed to JSAPArgsParsingCommandPlugin
  • The method TagHanderPlugin getDependentContentPluginRequestPrefixes() method has been renamed to usedContentPluginRequestPrefixes()
  • All BRJS model interfaces that form the model API have been moved to the org.bladerunnerjs.api package

More information about the API can be found in the JavaDocs, http://apidocs.bladerunnerjs.org/latest/java/index.html.

Plugin Ordering

Plugins were previously ordered by using methods on the Plugin API. This has now been moved to brjs.conf and so is used controllable. The new option in brjs.conf is orderedPlugins which can be used to define the order for any plugins where ordering is important, AssetPlugins and ContentPlugins.

The default ordering config is:

   - ThirdpartyAssetPlugin
   - BrowsableNodeSeedLocator
   - BRJSConformantAssetPlugin
   - '*'
   - I18nContentPlugin
   - AppMetadataContentPlugin
   - ThirdpartyContentPlugin
   - CommonJsContentPlugin
   - NamespacedJsContentPlugin
   - '*'

The name of each plugin should be included in the configuration. '*' can be used to match all other plugins.

HTML service improvements

The HTML service now allows templates to be provided inside <template/> tags, and automatically wraps any templates that aren't inside <template/> tags. Additionally, a fresh element or document fragment is provided when a template is requested, rather than providing the same DOM element each time.

HTML templates can now also be embedded in index.html rather than loading them via a separate XHR request. To do this you'll need to include <@html.bundle@/> in the <head> of the page, but can then continue to use the HTML service as before.

Existing apps and templates will still be compatible with these changes — see #1338 & #1352 for more information.

Apps can now live separate from the toolkit

The current working directory when brjs is executed is now used to detirmine where applications are on disk, meaning they can be placed anywhere and don't have to be placed next to the sdk directory.

Apps should be placed within a brjs-apps directory anywhere on the disk. If commands are executed inside of the brjs-apps directory this directory will be used to locate applications. Commands can also be executed from within an app, in which case the parent directory of the application will be used to locate apps.

This change is backwards compatible with previous app locations. If apps are contained within an apps directory which is next to the sdk directory the previous apps directory will be used and a deprecation warning logged.

Configurable App Version

The app version can now be configured via the serve and build-app commands. With either command the -v or --version flag can be used to provide a custom version, for example brjs build-app myApp -v 1.2.3. The current timestamp will be appended to the version to create a truely unique version in order to provide reliable cache invalidation. require(service!br.app-meta-service).getVersion() can then be used to access the version.

Setting the version via the serve command has the limitation where the version will be set for every app within that BRJS instance. For example if both the foo and bar apps exist and brjs serve --version 1.2.3 is run, 1.2.3 will be the version used for both apps.

Stricter Scope Enforcement

The bundling 'scope' is used to detirmine the valid locations that one asset can require on other assets. For example Blade classes cannot depend on another Blade class. Previously this enforcement was only applied within the Blade workbench, but was not enforced in the app. BladeRunnerJS will now perform additional checks to ensure that although all Blades are loaded within the App each Blade still cannot depend on one another.

This may be an imcompatability for apps written with previous version of BladeRunnerJS if one Blade depends on another Blade. This dependency should be broken by using Services so Blades do not directly depend on another another.

Locale Switching and Detection

The locale detection and redirection mechanism can now be overridden by changing the service implementations used during the locale redirection. This is useful if the users' locale preferences should be loaded from a database rather than be calculated from the browser.

The new locale switching changes has meant the need for the <base> has gone. The <@base.tag@/> plugin has now been deprecated and this line should be removed from index.html.

More information can be found at http://bladerunnerjs.org/docs/use/internationalization.md/multi-locale-apps.

Locale Switching During Tests

The active locale can now be configured during unit and acceptance tests. This can be done by adding the relevant locale requests to your jsTestDriver.conf file and calling require( 'br/I18n' ).setLocale("<locale>") at any point during the test.

For example given the following jsTestDriver.conf file.

server: http://localhost:4224
basepath: .
  - bundles/i18n/de.js
  - bundles/i18n/en.js
  - bundles/js/js.bundle
  - tests/**.js

The default active locale in tests would be en and the following test could be written to exercise the locale switching.

var i18n = require( 'br/I18n' );
assertEquals( 'January', i18n('br.i18n.date.month.january') );
assertEquals( 'Januar', i18n('br.i18n.date.month.january') );
assertEquals( 'January', i18n('br.i18n.date.month.january') );

API Documentation

Travis Build Status for v1.0-RC1:   Build Status

Closed Issues

The following issues labelled bug, feature, enhancement, experience, breaking-change, java-api, js-api or CaplinSupport have been closed:

  • accepting 'y' as the default stats plugin answer and adding more tests #1361
  • Allow templates to be embedded in index page #1352
  • change xmlns fields to bladerunnerjs.org URIs #1345
  • Html resource service improvements #1338
  • Ie jquery event fix #1337
  • Allow the version to be configured #1328
  • Add support for OptionsNodeList in popup windows #1325
  • Handle arrays in MapUtility#deepClone #1309
  • We need a selectionField which does not pick up "random" value when opti... #1308
  • MapUtility#deepClone doesn't clone arrays #1301
  • test-integration location doesnt work with default aspect #1297
  • Allow a meaningful version tag to be used #1290
  • Allow validators to be removed #1282
  • Aliasing not working if you require a class that refers to the interface #1268
  • bladeset workbench CSS resource bundle throws ClassCastException DirNode can't cast to AssetContainer #1238
  • [feature] BRJS should throw an exception if requiring something you shouldn't #1232
  • Missing open bracket on website code snippet http://bladerunnerjs.org/docs/use/getting_started/ #1215
  • legacyClear() patch doesn't work in practice #1213
  • output timestamp in --debug logs #1209
  • allows apps to live separately from the SDK #1154
  • Make the HTML resource service work for all known use cases #1116
  • move all API classes into an org.bladerunnerjs.api package and review the Plugin APIs #1085
  • base tag breaks links in single page apps #1059
  • Start doing a pure Java 8 test in Travis #1044
  • allow changing locales during tests #940
  • Can't run tests with --report flag on some IE11 machines #825
  • allows apps to push users to the locale forwarder if app locale doesnt match the users choice #804
  • Remove the / from the end of URLs if there is only a single locale #692
  • As a developer, when my require() fails, I want to know the locations BRJS attempted to find my dependency #565
  • BRJS prevents me saving/deleting files (locked files/folders) #446

67 issues closed; 30 labelled bug, feature, enhancement, experience, breaking-change, java-api, js-api or CaplinSupport from 1 milestones:

Found an Issue?

Parts of this release note have been auto-generated. If you notice any problems with it tell us