BladeRunnerJS 1.0
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 toJSAPArgsParsingCommandPlugin
- The method
TagHanderPlugin
getDependentContentPluginRequestPrefixes()
method has been renamed tousedContentPluginRequestPrefixes()
- 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, AssetPlugin
s and ContentPlugin
s.
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
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?
- https://github.com/BladeRunnerJS/brjs/issues for any existing issues
- https://github.com/BladeRunnerJS/brjs/issues/new to raise a new issues.
Parts of this release note have been auto-generated. If you notice any problems with it tell us