Giter Club home page Giter Club logo

laxar's Introduction

LaxarJS

Note: This project is no longer being actively maintained. Feel free to create a fork if you would like to continue using and/or developing the software.

Take a look at the documentation site to browse documentation for all releases of this artifact.

Why LaxarJS?

Find out why you would use LaxarJS and if it's the right tool for you. Then, explore the core concepts and browse the manuals in the documentation. Also, there is a glossary where you can lookup individual concepts, and a troubleshooting guide there for you if you need it.

Have a look at the LaxarJS website for demos and more information. Take a look at the documentation site to browse documentation for all releases.

Getting Started

Here are the basic instructions to get started.

Requirements

On your development machine, make sure that you have Node.js v6 or above (v4 might work, but there is no support).

Users of your application will need to have the following browser capabilities:

  • native ES5 support (no polyfills: MSIE < 9 is not supported)

  • Support for the following ES6 features (native or polyfilled):

    • Promise, Fetch
    • Array.from, Array.prototype.includes
    • Object.assign

Modern browsers have support for all of these, but polyfills for the listed ES6 features can be obtained by simply loading the LaxarJS polyfills bundle (dist/polyfills.js) using a script tag, before loading anything else. When using the generator (next step), your project will be setup for use with polyfills automatically.

Using the Generator

Use the generator-laxarjs2 for the Yeoman scaffolding tool to get started:

npm install -g yo generator-laxarjs2
mkdir my-app
cd my-app
yo laxarjs2

This will guide you through a couple of prompts in order to create your first application. There is a step-by-step tutorial containing a more detailed example.

Manual Setup

Using the generator is the recommended way of creating a LaxarJS application. However, knowledge about the manual project setup process is useful for a better understanding of LaxarJS and may help in some advanced use cases, such as migrating a project from a previous major version.

There are detailed instructions to create a project from scratch.

Hacking LaxarJS itself

Instead of using the compiled library within a project, you can also clone this repository:

git clone https://github.com/LaxarJS/laxar.git
cd laxar
npm install

To see changes in your application, either configure your project to work with the sources (e.g. by configuring a webpack alias), or rebuild the bundles:

npm run dist

To run the automated tests:

npm test

To generate HTML test runners for opening in your web browser, so that you can e.g. use the browser's developer tools for diagnostics:

npm start

Now you can select a spec-runner by browsing to http://localhost:8080/dist/lib/.

laxar's People

Contributors

fabianemmes avatar jpommerening avatar mkemmann avatar x1b avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laxar's Issues

FlowController breaks after navigateRequest to current place

Whenever the FlowController receives a navigateRequest event it changes the location to the requested place using the given parameters to initiate a route change via AngularJS. To prevent from leaking memory it then unsubscribes from further navigateRequest events. In the case the location doesn't actually change (i.e. place and parameters are the same as they were when navigating to the current location), the FlowController unsubscribes but no route change takes place. As a result subsequent navigateRequest events are ignored and navigation is broken until a browser refresh is triggered.

Documentation: document the widget specification schema

We should document how to write widget specifications, including:

  • differences from plain JSON schema (additionalProperties: false by default)
  • additions such as custom formats (see #42)
  • top-level stuff (integration types, controls...)

FileResourceProvider: bug when normalized rootpath is without trailing slash

When the root path is normalized (see #21) any trailing slash is removed, if the result is not only the host+port part of a domain or not the root dir (/). This now leads to different results when testing a file for existence within the listing. The tests of the file resource provider itself sadly didn't cover that case.

PageLoader doesn't check for duplicate composition ids

While there is a check for duplicated widget ids, there is non for duplicated composition ids. As composition ids are used to generate topics (i.e. names of actions or resources), this can lead to hard to debug naming clashes.

run_spec: widget.json loading (#5) breaks in "Karma"

The issue seems to be that Karma runs specs in its own HTML instead of our spec_runner.html.

Solution: resolve the widget.json URL relative to the spec directory (for which we already have an absolute URL)

testing: fix http_mock responseTransform

The httpMock in testing currently tries to simulate the $httpBackend behavior. In the long run, we probably want to drop httpMock in favor of $httpBackend completely.

Right now, we need make sure that the response conversion is not applied to non-OK responses and that it is not applied multiple times to the same response.

current place needs to be included in the didNavigate event of the FlowController

Currently only the navigation target requested in the navigateRequest event is included in the subsequent didNavigate event but not the actual place that was navigated to based on that target. As targets may lead to different places depending on the originating place, this information is ambiguous. Only places itself are unambiguous in the context of the full application.

jshintrc: Relax enforcement of dot notation

Although in general dot notation is better readable, some keys have to be written in bracket notation because they are reserved words or include characters that must be escaped. At least in such cases it is often more readable to write all neighboring property accesses in bracket notation than only some of them. Hence, at least in the aforementioned case, enforcing dot notation is only annoying.

Pages should allow disabling of widgets or compositions

It is often required to temporarily remove some widgets or compositions from a page, e.g. for debugging purposes. Currently this can only be achieved by deleting the according lines in the respective page or composition. To simplify this there should be a configuration option to disable a widget without the need to delete it.

Add temporary compatibility layer for didUpdate events using JSON Patch for incompatible widgets

To support a smooth transition from the old updates/data format in didUpdate events to the new JSON Patch format (see LaxarJS/laxar-patterns#12), there should be a temporary compatibility layer for widgets. For incompatible widgets the new JSON Patch format will be transformed into the current notation and vice versa.

In order to mark widgets as JSON Patch compatible, a new root property compatibility within widget.json files is introduced. This is an array of strings, currently only supporting "json-patch" as a value.
Example excerpt:

   ...
   "integration": {
      "type": "angular"
   },

   "compatibility": [ "json-patch" ],

   "features": {
   ...

Update bower

We should update Bower (and probably other tools).

LaxarJS uses Bower 1.2.8, the current version is 1.3.3.

This change (present since v1.3.0) in particular looks very promising, as it should solve our problems fetching dependencies over HTTP: bower/bower@08af876

root path in FileResourceProvider not normalized

The root path for file resources must be normalized. Otherwise the root path may e.g. still contain parent references (..) that are not contained in the path of the requested file and thus a matching against the file listings will fail.

portal: add 'topic-map' JSON format to widget loader

Sometimes, widgets have feature configuration in form of a map with topics as keys. Currently the corresponding schema has to be written using patternProperties which is cumbersome and error-prone. Instead, there should be a validation format 'topic-map' to perform the required validation of map keys.

portal: event bus tick still calls $apply more often than needed

Currently, another tick is scheduled whenever the event bus schedules an async callback to an empty queue. However, an empty queue does not in fact guarantee that events are not currently being processed. While the last callback is being processed, the queue is empty, and when that last callback schedules a new callback, an "empty" tick results, causing a completely unnecessary $apply operation.

To fix this, there should be a boolean semaphore which tracks if events are currently being processed, and prevents a new timeout from being set if that is the case.

configuration: consolidate and document existing options

Currently, the LaxarJS configuration is not documented, and configuration options do not follow a consistent naming scheme.

Options should always be prefixed with the module that they belong to (for example file_resource_provider.fileListings). More importantly, documentation on the existing options and their default values is needed.

The change must leave the existing configuration keys working, but should deprecate their use.

Portal must initialize i18n on $rootScope

This is needed to make i18n controls work in non-i18n widgets (where the locale isn't available via the event bus). Note that this change also effects the setup of the widget testbed.

Optimize WidgetLoader

The WidgetLoader can be optimized by avoiding duplicate request to widget templates, and by avoiding the unnecessary use of ngClass and ngRepeat.

Improve error messages of JSON validator

Currently the JSON validator only prints the name of the erroneous attribute when the validation of a property by schema fails. In many cases this is not helpful at all, if for example a widget has many features, each with e.g. a property resource and the error message only says that the configuration for resource is insufficient. The expected output is the full path to the property, e.g. someFeature.resource.

testbed does not load controls declared in widget.json

The testbed needs to simulate the angular-dependencies mechanism which is provided by the LaxarJS portal: Controls declared in the widget.json must be loaded and registered as AngularJS-modules with the angular-mock.

Get the tests running in Karma again!

This is odd โ€“ the spec runner is trying to load the widget.json when running the LaxarJS specs.
This would not be that bad if it just resulted in a 404 and the tests would just run anyway (as they do when viewing them in a browser).
It looks the problem is the Karma default configuration that gets injected by grunt-laxar: Since we have no connect server running, the proxying does not work.

Can't run widget tests when require baseUrl points to `bower_components`

Looking at the require_config.js one is tempted to use bower_compontents as the baseUrl as that would shorten many of the defined paths.

Unfortunately the run_spec.js does not handle that case properly yet:

Error: expected spec URL to start with /base/bower_components/
at /tmp/test_application/bower_components/laxar/lib/testing/run_spec.js:36

It should be possible to solve this by trying to determine the relative (RequireJS doesn't like absolute URLs) path from the baseUrl to the specs.

For example if the baseUrl is /bower_components and the Widget specs are at /includes/widgets/test_widgets/my_test_widget/spec, the script should use ../includes/widgets/test_widgets/my_test_widget/spec as the spec path.

Only load the page relevant for the current place

Currently all pages are resolved as soon as the portal is bootstrapped, which introduces at least to problems:

  • Increased load time on each full reload of the portal because of many unnecessary HTTP requests and additional, unneeded assembly steps
  • More memory consumption as the full set of pages resides as object tree in the memory
    The behavior should thus be changed to only load a page as soon as it is requested by the flow controller.

portal: do not pause between event bus ticks, only $apply when needed

Currently, the portal uses $timeout as the nextTick implementation for the event bus. This causes a full AngularJS digest-cycle after each tick, and also lets (most) browsers think that they should do a repaint.

Instead, all ticks should occur directly in a row, followed by a $digest cycle. If new events were produces during the cycle, the process repeats.

EventBus: Resolve promises directly from the event bus, not from $apply

Currently, promises generated by eventBus.publish and eventBus.publishAndGatherReplies are delivered during $scope.$apply after each event bus tick, even if already resolved during the event sequence. This often leads to a new sequence of events and thus a new tick being scheduled, which in turn causes another $apply operation.

Because $apply is very expensive, especially on larger pages, we want to make sure that it is called only once for each sequence of events. To ensure this, the event bus should be able to resolve promises using its own tick-scheduler (as provided by portal-services).

testing: make sure that session storage access during testing is mocked

Currently, running widget spec tests included in an application may affect the theme of the same app, if subsequently loaded into the same browser window.

We need to make sure that widget spec tests either do not access the same session storage (e.g. by having reliable mocking) or that there is a cleanup on testBed.tearDown

FileResourceProvider: use embedded file resources

Once the directory_tree task from grunt-laxar is able to embed file resources, the FileResourceProvider needs to be modified in order to pick up embedded file resources.

For regular development, there needs to be an option where embedded file listings are ignored.

Allow JSON schema draft v4 in widget features specifications (widget.json)

Although the new JSON schema validator will support JSON schema draft v4 starting with version 0.11.0 of LaxarJS, this currently isn't supported by the widget loader. The widget loader validates the configuration provided for a widget against the partial schema found under the features key in the according widget specification. Currently it is assumed that there is always the same wrapper around the features map that defines an element of type object of which the single features are the properties.
So instead of writing:

"features": {
   "$schema": "http://json-schema.org/draft-04/schema#",
   "type": "object",
   "properties": {
      "featureOne": { ... },
      "featureTwo": { ... }
   }
}

this currently is sufficient and expected by the widget loader:

"features": {
   "featureOne": { ... },
   "featureTwo": { ... }
}

As a matter of fact the complete version above is needed to be able to define the necessary $schema property that defines the version of the schema. To cut a long story short: The widget loader needs to support both types of features specification to be backwards compatible and additionally provide the ability to use JSON schema draft v4 in new widgets or when refactoring existing widgets.

Portal: decouple controller instantiation from AngularJS lifecycle

Currently, the instantiation of Widget- and Activity-Controllers is tightly coupled to their representation in the DOM and to the initialization of their containing widget area. This causes the widget controllers to wait for templates in order to initialize, and it causes a number of unnecessary apply cycles in order to link each level of the widget hierarchy.

Because controllers are not supposed to have direct ties to their DOM representation, it would be sensible to instantiate them as soon as possible, so that they can start to perform service requests and initialization logic.

The associated AngularJS templates could then be compiled (off-document) in a second step, also without waiting for their containing DOM widget areas to become available. Once all widget templates are compiled and linked individually, the page can be assembled and attached to the page-DOM.

As an added benefit, widget DOM representation would reflect a fairly "done" state directly upon initial linking (e.g. widgets would be using the languageTag received over the event bus from the start), so that unnecessary browser repaints are avoided.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.