Skip to content

BladeRunnerJS 1.0

Compare
Choose a tag to compare
@brjs-ci brjs-ci released this 19 Jun 15:46
· 920 commits to master since this release

BladeRunnerJS 1.0

1.0 Features and Improvements

1.0 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

Plugin API changes

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

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

service! no longer caches

The service! notation no longer permanently caches the services that are returned, so that changes to the ServiceRegistry are reflected in the next require('service!my-service') invocation that is made.

Since ServiceRegister.clear() is automatically invoked at the end of every test, this may cause tests to break for tests that require services for the duration of the test suite (e.g. within describe()), rather than at the beginning of each test (e.g. within beforeEach()).

Clock utility must be installed before it is used

BRJS provides a 'Clock' class inside of 'jsunitextensions' which allows tests to validate behaviour inside of 'setTimeout' callbacks. Before the utility can be used it must now be 'installed' in the test setup and uninstall in the tear down, for example your test might look like the following:

require('jsunitextensions');
var MyTest = TestCase('MyTest');

MyTest.prototype.setUp = function() {
    Clock.install();
}
MyTest.prototype.tearDown = function() {
    Clock.uninstall();
}

MyTest.prototype.testSomething = function() {
    // something that sets a timeout
    Clock.tick(1000);
    // verify the behaviour
}

Presenter no longer clones templates and removes IDs

Previously the Presenter library was responsible for cloning templates returned from the HTML service and removing their IDs. This logic has now been moved into the HTML service. For most apps this will have no affect, however any apps or tests that were previously relying on being able to change a template via the DOM and have this persisted each time the template was requested will need to be changed. It's also worth noting that it's no longer required to clone templates or remove IDs as this is now done before the template is returned from the HTML service.

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.

AssetPlugin

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:

...
orderedPlugins:
    AssetPlugin:
   - ThirdpartyAssetPlugin
   - BrowsableNodeSeedLocator
   - BRJSConformantAssetPlugin
   - '*'
   ContentPlugin:
   - 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

Localisation pages must have a DOCTYPE

The HTML service has been changed to make use of template elements. A shim is provided so IE8+ can use template elements but this requires the browser to be in 'strict mode'. To enable this pages should have a DOCTYPE, for example <!DOCTYPE html>.

getHTMLTemplate(id) deprecated

The getHTMLTemplate(id) method has now been deprecated in favor of getTemplateElement(id) & getTemplateFragment(id). getTemplateElement(id) will return a cloned element for the template ID provided if the template contains a single 'top level' element, otherwise an exception will be thrown. getTemplateFragment(id) will return a document fragment, a collection of cloned elements, for the template ID and is the recommended method for retrieving templates.

Embedded HTML templates

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 separately 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/#understanding-how-locale-switching-is-handled-in-brjs.

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: .
load:
  - bundles/i18n/de.js
  - bundles/i18n/en.js
  - bundles/js/js.bundle
test:
  - 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') );
i18n.setLocale("de");
assertEquals( 'Januar', i18n('br.i18n.date.month.january') );
i18n.setLocale("en");
assertEquals( 'January', i18n('br.i18n.date.month.january') );

KnockoutComponent Binding

Previously Knockout bindings were performed when KnockoutComponent.getElement() was called, this no longer happens automatically. An 'attach' event will now need to be triggered on the Component after attaching it's element to the DOM. e.g.

pageElement.appendChild(frame.getElement())
frame.trigger('attach');

See https://github.com/BladeRunnerJS/brjs/releases/tag/v1.0-RC1 and https://github.com/BladeRunnerJS/brjs/issues?q=milestone%3A%221.0+RC1%22+is%3Aclosed for other issues closed since the last major release.


API Documentation

Travis Build Status for v1.0:   Build Status

Closed Issues

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

  • 1.0 perf review #1420
  • calling createElement above embedded HTML templates #1419
  • Time to run the tests has increased #1413
  • src-test doesn't work as it used to #1412
  • apps folder must not become legacy behaviour #1408
  • Fixed a bug for TooltipControl.js where the tooltip would not render correctly #1407
  • Remove 'caplin' and 'caplinx' from reserved namespaces #1404
  • FXMotif first load taking a long time #1400
  • Fix for Verifier parsing values with new line characters #1395
  • Newly imported apps no longer show in the dashboard #1392
  • IIFE warning emitted for non CommonJS code #1391
  • Renamspacing fixes #1388
  • apps should be created inside the working dir #1386
  • Can't run tests if project is in a symlinked path #1384
  • Initialize knockout plug-ins after template added to page #1379
  • Strange bindings within bindingHandler using C3 library #1374
  • Elements not fully initialized at binding time #1373
  • Better support for Jquery plugins within ko bindingHandlers #1372
  • Can't run tests from the SDK folder #1342
  • BRJS JSDoc template improvements #1273
  • document new features #1212

51 issues closed; 21 labelled bug, feature, enhancement, experience, breaking-change, java-api, js-api or CaplinSupport from 1 milestones:
https://github.com/BladeRunnerJS/brjs/issues?milestone=31&state=closed

Found an Issue?

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